Rails 3 find all related has_many entries: via

I would like to list all posts related to a specific category and class.

I have:

class Post < ActiveRecord::Base has_many :category_posts has_many :categories, :through => :category_posts has_many :classroom_posts has_many :classrooms, :through => :classroom_posts end class Category < ActiveRecord::Base has_many :category_posts has_many :posts, :through => :category_posts end class CategoryPost < ActiveRecord::Base belongs_to :category belongs_to :post end class Classroom < ActiveRecord::Base has_many :classroom_posts has_many :posts, :through => :classroom_posts end class ClassroomPost < ActiveRecord::Base belongs_to :classroom belongs_to :post end 

And I want to do something like this

 Post.where(["category.id = ? AND classroom.id = ?", params[:category_id], params[:classroom_id]]) 

This is really a very simple task, but I don’t know what I need to search for (keywords).

This is the same problem as this , but in rails.

EDIT : I added additional information to the question. This works, but only if I have both options. A witch is not always like that - I do not know what parameters will be specified.

 Post.joins(:categories, :classrooms).where(["categories.id = ? AND classrooms.id = ?", params[:classroom_id], params[:category_id]]) 
+7
ruby ruby-on-rails associations model
source share
4 answers
 Category.find(params[:category_id]).posts 

Also check out the guides:

+4
source share

Here is what I would do in Rails 3:

In post.rb :

 def self.in_category(category_id) if category_id.present? join(:category_posts).where(category_posts: {category_id: category_id}) else self end end def self.in_classroom(classroom_id) if classroom_id.present? join(:classroom_posts).where(classroom_posts: {classroom_id: category_id}) else self end end 

I do not join Classroom or Category , as it does more work for the DBMS, and this is not required.

Now you can do:

 Post.in_category(params[:category_id]).in_classroom(params[:classroom_id]) 

I have not tested it. So feel free to ask if necessary.

+4
source share

I think this should work:

 Post.joins(:category_posts, :classroom_posts) .where( ["category_posts.category_id = ? AND classroom_posts.classroom_id = ?", params[:category_id], params[:classroom_id]]) 

This translates to SQL as:

 SELECT p.* FROM posts AS p INNER JOIN category_posts AS cap ON cap.id = p.category_posts_id INNER JOIN classroom_posts AS clp ON clpid = p.classroom_posts_id WHERE cap.category_id = '1' AND clp.classroom_id = '1' ; 

Regarding the use of: include or join on Post , look at this answer on stackoverflow.

+2
source share

It looks like you need if status.

 if params[:category_id] && params[:classroom_id] Post.joins(:categories, :classrooms).where("classrooms.id" => params[:classroom_id], "categories.id" => params[:category_id]]) elsif params[:category_id] Category.find(params[:category_id]).posts else Classroom.find(params[:classroom_id]).posts end 
0
source share

All Articles