所以我对范围很陌生,并且不太了解它们。我们说我有2个模型,Project
和Ticket
:
class Project < ActiveRecord::Base
has_many :tickets
end
class Ticket < ActiveRecord::Base
belongs_to :project
end
我习惯这样编码来访问门票中的相关数据:
Project.find(1).tickets.each do |ticket|
puts ticket.name
end
我创建了新范围:
scope :default, -> { where(default: true) }
现在当我使用Project.default
时,我会回来ActiveRecord::Relation
并且不知道如何访问关联的tickets
?
答案 0 :(得分:2)
Project.default确实会返回ActiveRecord::Relation
,这是一个'待触发'查询。一旦你开始循环等,就会触发查询,这对你来说是透明的。
如果您想从项目中获取门票,首先我建议您将它们包含在您的查询中,以避免N + 1。这样做:
projects = Project.default.includes(:tickets)
然后访问特定项目的门票:
project = projects.first
project.tickets
如果希望方法始终返回单个对象:
class Project < ActiveRecord::Base
has_many :tickets
def self.get_default_with_tickets
Project.where(default: true).includes(:tickets).first
end
end
然后:
Project.get_default_with_tickets #=> your_project
务必处理案件:
答案 1 :(得分:0)
scope基本上只是一个class method(在非初始化模型上触发的一个):
class Project < ActiveRecord::Base
has_many :tickets
scope :defaults, -> { where(default: true) }
end
这意味着如果你这样做:
@defaults = Project.defaults
...您将所有project
个对象恢复为具有属性default
为真的
这与此相同:
class Project < ActiveRecord::Base
has_many :tickets
def self.defaults
where(default: true)
end
end
错误强>
你获得关系的原因是因为当你使用where
时,你基本上得到了一个“数组”数据(而不是只有一个记录)。如果您.each
通过数据或只返回.first
,您将获得一个可以输出的实际对象:
@defaults = Project.defaults
@defaults.each do |project|
project.tickets #-> associated tickets
end
答案 2 :(得分:0)
使用all
或first
完成查询。
#get all default projects
Project.default.all
#get the first default project
Project.default.first