Ruby-on-rails Rails 3 查找所有关联记录 has_many :through
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2798742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails 3 find all associated records has_many :through
提问by Sergey
I would like to list all posts that are connected with some specific category and classroom.
我想列出与某些特定类别和教室相关的所有帖子。
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 wanna do something like this
我想做这样的事情
Post.where(["category.id = ? AND classroom.id = ?", params[:category_id], params[:classroom_id]])
It indeed is very simple task, but I don't know what I should be looking for (keywords).
这确实是非常简单的任务,但我不知道我应该寻找什么(关键字)。
It's the same problem like this, but in rails.
这就像同样的问题,这个,但是在轨道上。
EDIT: I added more details to the question. This works, but only if I have both params specified. Witch is not always the case - I dont know what params would be specified.
编辑:我在问题中添加了更多细节。这有效,但前提是我指定了两个参数。女巫并非总是如此 - 我不知道会指定什么参数。
Post.joins(:categories, :classrooms).where(["categories.id = ? AND classrooms.id = ?", params[:classroom_id], params[:category_id]])
回答by yfeldblum
Category.find(params[:category_id]).posts
Also take a look at the guides:
也看看指南:
回答by jbescoyez
Here is what I would do in Rails 3:
这是我在 Rails 3 中要做的事情:
In post.rb:
在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 Classroomor Categorysince it makes more work for DBMS and this is not required.
我不加入,Classroom或者Category因为它为 DBMS 做了更多工作,这不是必需的。
Now, you can do:
现在,你可以这样做:
Post.in_category(params[:category_id]).in_classroom(params[:classroom_id])
I haven't tested it though. So do not hesitated to ask if needed.
不过我还没有测试过。因此,如果需要,请毫不犹豫地询问。
回答by jake
I think that 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 will traslate to a SQL like :
这将转换为 SQL,如:
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'
;
As to whether to use :include or joins on Postlook at this answeron stackoverflow.
至于是使用 :include 还是 joins ,请Post查看stackoverflow上的这个答案。
回答by Dan Healy
Sounds like you need an if statment.
听起来你需要一个 if 语句。
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

