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

Ransacker blocks should have access to query args #433

Closed
fabn opened this issue Sep 22, 2014 · 2 comments
Closed

Ransacker blocks should have access to query args #433

fabn opened this issue Sep 22, 2014 · 2 comments

Comments

@fabn
Copy link

fabn commented Sep 22, 2014

I'm investigating on how to deal with HABTM associations, here's my use case

class Article
  has_and_belongs_to_many :categories
end

class Category
  has_and_belongs_to_many :articles
end

My goal is to make Article.search(categories_id_in: [1,2,3]) returns articles having all three categories. This was asked in #112, #187 and some other places.

While the in and in_any predicates are working out of the box <plural_association_id>_in_all produces a wrong query as you can see here:

This is correct, produces articles with any of the given categories

1] pry(main)> Article.search(categories_id_in: [1,2,3]).result.to_sql
# => "SELECT `articles`.* FROM `articles`
  LEFT OUTER JOIN `articles_categories` ON `articles_categories`.`article_id` = `articles`.`id`
  LEFT OUTER JOIN `categories` ON `categories`.`id` = `articles_categories`.`category_id`
  WHERE `categories`.`id` IN (1, 2, 3)"

This is also correct, produces same result as above with a verbose query

[2] pry(main)> Article.search(categories_id_in_any: [1,2,3]).result.to_sql
# => "SELECT `articles`.* FROM `articles`
  LEFT OUTER JOIN `articles_categories` ON `articles_categories`.`article_id` = `articles`.`id`
  LEFT OUTER JOIN `categories` ON `categories`.`id` = `articles_categories`.`category_id`
  WHERE ((`categories`.`id` IN (1) OR `categories`.`id` IN (2) OR `categories`.`id` IN (3)))"

This is clearly wrong, there cannot be a single row with category_id equal to 1, 2 and 3 at the same time

[3] pry(main)> Article.search(categories_id_in_all: [1,2,3]).result.to_sql
# => "SELECT `articles`.* FROM `articles`
  LEFT OUTER JOIN `articles_categories` ON `articles_categories`.`article_id` = `articles`.`id`
  LEFT OUTER JOIN `categories` ON `categories`.`id` = `articles_categories`.`category_id`
  WHERE ((`categories`.`id` IN (1) AND `categories`.`id` IN (2) AND `categories`.`id` IN (3)))"

I was able to obtain the right results by doing this query

[5] pry(main)> Article.search(categories_id_in:[526,527,556]).result
  .group('articles.id').having('COUNT(categories.id) = ?', 3).to_sql
# => "SELECT `articles`.* FROM `articles`
  LEFT OUTER JOIN `articles_categories` ON `articles_categories`.`article_id` = `articles`.`id`
  LEFT OUTER JOIN `categories` ON `categories`.`id` = `articles_categories`.`category_id`
  WHERE `categories`.`id` IN (526, 527, 556)
  GROUP BY articles.id
  HAVING COUNT(categories.id) = 3"

Now I'd like to try to embed the part group('articles.id').having('COUNT(categories.id) = ?', 3) into a ransacker, however inside ransacker block I do not have access to the array arguments and I cannot build the having part.

Is this something that should be added to the ransacker api?

Is there any other way to accomplish this?

@jonatack jonatack closed this as completed Nov 5, 2014
@jonatack jonatack reopened this Nov 5, 2014
@jonatack
Copy link
Contributor

Hi @fabn, hopefully #513 solves this for you. Closing for now; please re-open if there is still an issue.

@bo-oz
Copy link

bo-oz commented Nov 24, 2015

I have the same problem as fabn... I've read #513, but don't understand how that solves his question. Is there some documentation available on querying HABTM relationship for records that have each of the specified related records (and not OR like in fabn's example queries 1 and 2)

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

No branches or pull requests

3 participants