ruby on rails -简单的作用域和关联



所以我是作用域的新手,并不是很了解它们。假设我有两个模型,ProjectTicket:

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 ?

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

一定要处理好这些情况:

  • 当有多个匹配
  • 时当没有匹配时

作用域基本上就是一个类方法(在未初始化的模型上触发的方法):

class Project < ActiveRecord::Base
 has_many :tickets
 scope :defaults, -> { where(default: true) }
end

这意味着如果你这样做:

@defaults = Project.defaults

…你会得到所有具有属性default为true的project对象

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

使用allfirst完成查询。

#get all default projects
Project.default.all 
#get the first default project
Project.default.first

相关内容

  • 没有找到相关文章

最新更新