我有3个型号:
class User < ActiveRecord::Base
has_many :categories
has_many :links, through: :categories
end
class Category < ActiveRecord::Base
belongs_to :user
has_many :links
end
class Link < ActiveRecord::Base
belongs_to :category
end
对于给定的用户,我想找到他喜欢的字段等于true的所有链接。我正在从'rails guides'学习rails并且我在那里搜索了对此的简单查询,但我没有找到任何东西。最后我使用select iterator解决了问题:
@links = current_user.links.select{ |l| l.favorite }
但我不确定这是一个很好的解决方案。怎么用rails方式?
答案 0 :(得分:4)
要添加到@Pierre Michard
的答案,您可能还希望查看ActiveRecord Association Extensions,它基本上会取代scope
模型中的Link
:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :categories
has_many :links, through: :categories do
def favorites
where favorite: true
end
end
end
这将允许您致电:
@links = current_user.links.favorites
答案 1 :(得分:3)
工作正常,但该代码生成的SQL查询将类似于
SELECT * FROM links where links.user_id = ?
然后,您感兴趣的链接将被select方法过滤。 如果您的用户有很多链接,而且很少有人喜欢,那么以这种方式选择收藏夹可能会更有效:
@links = current_user.links.where(favorite: true)
这会产生这种查询:
SELECT * FROM links where links.user_id = ? AND links.favorite = 't'
您可以在链接模型中创建范围以过滤收藏的链接。
class Links < ActiveRecord::Base
scope :favorites, -> { where(favorite: true) }
end
相应的查询:
@links = current_user.links.favorites
这可以更有效,因为这将创建更少的ActiveModel对象。
答案 2 :(得分:-1)
需要多对多的关系,
class User < ActiveRecord::Base
has_many :categories
has_many :links, through: :categories
end
class Category < ActiveRecord::Base
belongs_to :user
belongs_to :link
end
class Link < ActiveRecord::Base
has_many :categories
has_many :users, through: :categories
end
然后你可以获取最喜欢的列为真的链接记录,
@links = current_user.categories.include(:links).where('links.favorite = ?', true)