通过对象实例调用 class 方法
Calling a class method through an object instance
Railscasts #4 使用此示例代码:
class Task < ActiveRecord::Base
belongs_to :project
def self.find_incomplete
find_all_by_complete(:false, :order => "created_at DESC")
end
end
class ProjectsController < ApplicationController
def show
@project = Project.find(params[:id])
@tasks = @project.tasks.find_incomplete
end
end
使用 @project.tasks.find_incomplete
,仅查找属于该特定 Project
实例的不完整订单。
我希望该调用等同于 Task.find_incomplete
,但事实并非如此。这个怎么可能? Rails(或 Ruby)现在如何为那个 Project
实例中的那些特定 Task
调用该方法?
之所以可行,是因为合并了 ActiveRecord 关系的范围。这并不是说 find_incomplete
是 运行 单个任务实例。
@project.tasks
为该项目实例创建任务的 ActiveRecord 范围,然后当您的 find_incomplete
方法被调用时该范围仍然有效。
查看此处的文档:http://guides.rubyonrails.org/active_record_querying.html#scopes
您的 find_incomplete
方法与文档中 self.published
示例的工作方式相同。
想想下面的 SQL 查询 运行:
@project.tasks
会创建 where
条件,例如 SELECT * FROM projects WHERE project_id = <project_id>
find_all_by_complete
然后在 and
条件下合并 complete = 0
我认为另一个可能有用的谜题是 @project.tasks
不仅仅是 Task
对象的简单数组,尽管如果您键入 project.tasks
在 Rails 控制台中。 project.tasks
实际上是一个 Active Record 关系对象(或者更准确地说是一个代理)
这有很多原因和好处,但主要的 2 个是它允许链接,它允许基础查询 运行 按需 if/when 需要。
关系有一系列关于如何委托方法调用的规则,其中之一是在关联对象的 class 上调用 class 方法。 (该关系知道它是与 Tasks
的关系)
所以当你写 tasks.find_incomplete
仍然等于 Task.find_incomplete
时你是正确的,除了当通过 project.tasks
调用 find_incomplete
时范围缩小到 project_id
已经生效。
Railscasts #4 使用此示例代码:
class Task < ActiveRecord::Base
belongs_to :project
def self.find_incomplete
find_all_by_complete(:false, :order => "created_at DESC")
end
end
class ProjectsController < ApplicationController
def show
@project = Project.find(params[:id])
@tasks = @project.tasks.find_incomplete
end
end
使用 @project.tasks.find_incomplete
,仅查找属于该特定 Project
实例的不完整订单。
我希望该调用等同于 Task.find_incomplete
,但事实并非如此。这个怎么可能? Rails(或 Ruby)现在如何为那个 Project
实例中的那些特定 Task
调用该方法?
之所以可行,是因为合并了 ActiveRecord 关系的范围。这并不是说 find_incomplete
是 运行 单个任务实例。
@project.tasks
为该项目实例创建任务的 ActiveRecord 范围,然后当您的 find_incomplete
方法被调用时该范围仍然有效。
查看此处的文档:http://guides.rubyonrails.org/active_record_querying.html#scopes
您的 find_incomplete
方法与文档中 self.published
示例的工作方式相同。
想想下面的 SQL 查询 运行:
@project.tasks
会创建 where
条件,例如 SELECT * FROM projects WHERE project_id = <project_id>
find_all_by_complete
然后在 and
条件下合并 complete = 0
我认为另一个可能有用的谜题是 @project.tasks
不仅仅是 Task
对象的简单数组,尽管如果您键入 project.tasks
在 Rails 控制台中。 project.tasks
实际上是一个 Active Record 关系对象(或者更准确地说是一个代理)
这有很多原因和好处,但主要的 2 个是它允许链接,它允许基础查询 运行 按需 if/when 需要。
关系有一系列关于如何委托方法调用的规则,其中之一是在关联对象的 class 上调用 class 方法。 (该关系知道它是与 Tasks
的关系)
所以当你写 tasks.find_incomplete
仍然等于 Task.find_incomplete
时你是正确的,除了当通过 project.tasks
调用 find_incomplete
时范围缩小到 project_id
已经生效。