Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for associations #38

Closed
mackstar opened this issue Jul 16, 2017 · 10 comments
Closed

Support for associations #38

mackstar opened this issue Jul 16, 2017 · 10 comments

Comments

@mackstar
Copy link

Really like the library but have not been able to see how to do searches on associations which is huge need when using a relational database. Many thanks.

@rcdilorenzo
Copy link
Owner

@mackstar You should be able to simply reference the foreign key (e.g. user_id for a relationship to a user). Feel free to re-open the issue if that does not resolve your problem. Sorry for the delayed response.

@jaysson
Copy link

jaysson commented Feb 1, 2018

It works for one to one associations, but not for many to many and one to many.

@Merff
Copy link

Merff commented Feb 1, 2018

@rcdilorenzo Hi, +1. How to search by many to many?

@rcdilorenzo
Copy link
Owner

It should work at least for for one-to-many relationships if the key is specified on the foreign object. Please let me know if this doesn't work. For many-to-many, I believe @jaysson and @Merff are correct. I'll re-open.

@rcdilorenzo rcdilorenzo reopened this Feb 1, 2018
@rcdilorenzo rcdilorenzo added bug and removed bug labels Feb 1, 2018
@Merff
Copy link

Merff commented Feb 2, 2018

Given example:
I have two models with standart many_to_many association and join table.

defmodule Tag do
  ...
  schema "tags" do
    field :name, :string

    many_to_many :posts, Post, join_through: "posts_tags"
  end
end

defmodule Post do
  ...
  schema "posts" do
    ...
    many_to_many :tags, Tag, join_through: "posts_tags",
  end
end

Join table :posts_tags, has
  :post_id, references(:posts)
  :tag_id, references(:tags)

And I have select form with multiselect for filter posts by tags:
= multiple_select f, :tags, Enum.map(@tags, &{&1.name, &1.id})

Now I do smth like this for filtering:

def list_posts(params)
  tags_params = Map.get(params, "tags")
  filtrex_params = Map.drop(params, ["tags"])

  case Filtrex.parse_params(config, filtrex_params) do
    {:ok, filter} -> Filtrex.query(Post, filter)
    {:error, error} -> {:error, error}
  end
  |> custom_filters(tags_params) |> Repo.all
end

def custom_filters(query, nil), do: query
def custom_filters(query, tags) do
   tags_ids = Enum.map(tags, &String.to_integer(&1))
   from p in query, join: t in assoc(p, :tags), group_by: p.id, having: fragment("? <@ array_agg(?)", ^tags_ids, t.id)
end

It works fine for many_to_many and multi select.
Have better solution?
@rcdilorenzo

@rcdilorenzo
Copy link
Owner

@Merff and @mackstar... I'm trying to recall the status of this issue. Is this still something that needs to be resolved?

@Merff
Copy link

Merff commented Jun 27, 2018

for me no longer relevant =)

@mackstar
Copy link
Author

I think @Merff 's previous instructions show how to use this adequately. The status is closed.

@rcdilorenzo
Copy link
Owner

Okay, that's what I thought. Thanks guys.

@JohnKacz
Copy link
Contributor

It seems like @Merff's solution filters posts that match all of the tag_ids, right? What if you wanted posts that had any of the tags in the tap_params list?

I'm traying to wrap my head around the range function operators and the aggregate functions here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants