Skip to content
New issue

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

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

Already on GitHub? # 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.

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

No branches or pull requests

5 participants