Rails 关联方法如何工作?

2024-03-30

Rails 关联方法如何工作?让我们考虑这个例子

class User < ActiveRecord::Base
   has_many :articles
end

class Article < ActiveRecord::Base
   belongs_to :user
end

现在我可以做类似的事情

@user = User.find(:first)
@user.articles

这会获取属于该用户的文章。到目前为止,一切都很好。

现在,我可以在一些条件下继续查找这些文章。

@user.articles.find(:all, :conditions => {:sector_id => 3})

或者简单地声明和关联方法,例如

class User < ActiveRecord::Base
   has_many :articles do
     def of_sector(sector_id)
       find(:all, :conditions => {:sector_id => sector_id})
     end
   end
end

And do

@user.articles.of_sector(3)

现在我的问题是,这是怎么回事find在数组上工作ActiveRecord使用关联方法获取对象?因为如果我们实现自己的User调用实例方法articles并编写我们自己的实现,它为我们提供了与关联方法完全相同的结果,即在获取数组上的查找ActiveRecord对象无法工作。

我的猜测是,关联方法将某些属性附加到获取的对象数组中,从而可以使用以下命令进行进一步查询find和别的ActiveRecord方法。在这种情况下,代码执行的顺序是什么?我如何验证这一点?


它实际上是如何工作的,关联对象是一个“代理对象”。具体班级是关联代理 http://github.com/rails/rails/blob/2-3-stable/activerecord/lib/active_record/associations/association_proxy.rb。如果您查看该文件的第 52 行,您将看到:

instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }

通过这样做,像这样的方法class不再存在于该对象上。所以如果你打电话class在此对象上,您将缺少方法。所以,有一个method_missing为将方法调用转发到“目标”的代理对象实现:

def method_missing(method, *args)
  if load_target
    unless @target.respond_to?(method)
      message = "undefined method `#{method.to_s}' for \"#{@target}\":#{@target.class.to_s}"
      raise NoMethodError, message
    end

    if block_given?
      @target.send(method, *args)  { |*block_args| yield(*block_args) }
    else
      @target.send(method, *args)
    end
  end
end

目标是一个数组,所以当你调用class在这个对象上,它说它是一个数组,但这只是因为目标是一个数组,实际的类是一个 AssociationProxy,但你再也看不到它了。

所以您添加的所有方法,例如of_sector,被添加到关联代理中,因此它们会被直接调用。方法如[] and class未在关联代理上定义,因此它们被发送到目标(一个数组)。

为了帮助您了解这是如何发生的,请将以下内容添加到您的 Association_proxy.rb 本地副本中该文件的第 217 行:

Rails.logger.info "AssociationProxy forwarding call to `#{method.to_s}' method to \"#{@target}\":#{@target.class.to_s}" 

如果您不知道该文件在哪里,请使用命令gem which 'active_record/associations/association_proxy'会告诉你的。现在当你打电话时class在 AssociationProxy 上,您将看到一条日志消息,告诉您它正在将其发送到目标,这应该可以让您更清楚地了解正在发生的情况。这全部适用于 Rails 2.3.2,在其他版本中可能会发生变化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rails 关联方法如何工作? 的相关文章

随机推荐

  • 方案 - 列表之和

    我正在尝试实现一个计算 list 的函数 其名称是sum define sum elemList if null elemList car elemList sum cdr elemList 0 上面的实现给出了错误的结果 例如 gt su
  • 如何删除 Docker 镜像?

    我有以下图像 alex alexvps sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
  • ruby on Rails 中的 Facebook 重定向 url 打开 ssl 错误

    我已经按照 Ryan 在第 235 集中解释的那样关注了omniauth devise facebook 应用程序 在用户授权后 我们在以下位置收到错误http localhost 3000 auth facebook callback c
  • 创建像 Office 2010 一样的动画启动屏幕

    如何使用 C 创建像 Office 2010 中那样的动画启动屏幕 这个问题是关于winform还是wpf 如果是关于wpf的 动画启动屏幕只不过是加载 主窗口 时显示的 wpf 窗口 您可以按照 wischi 的说明使用 Expressi
  • jquery 移动和 flot 库

    我正在一个小型 jquery 移动框架站点中实现 flot 包含flot的页面 内容div位于辅助页面上 第一次显示浮动页面时 图表呈现得很好 返回到主页并再次前进到浮动页面时 图表不会呈现 内容来自 asp mvc 视图 div div
  • AS3 到 JS 编译器

    我偶然发现了 AS3 到 JS 编译器Jangaroo http www jangaroo net home 看起来它可能是一个有用的工具 因为它支持很多我喜欢的 AS3 功能 还有其他这样的编译器吗 我可以使用其他语言吗 学习一下 编译成
  • 您可以在 display:table-cell 中相对或绝对定位项目吗?

    我有一个链接 我希望它始终位于其所在单元格的右下角 现在该链接位于 元素中 我尝试同时进行绝对定位和相对定位 但可以获得我想要的效果 我有一排有 4 个单元格 当尝试应用绝对位置时 它将元素带到右侧的最后一个单元格 而不是仅仅将其放置在它所
  • matlab中无for循环的行列矩阵乘法

    我遇到以下问题 并且无法想出没有 for 循环的解决方法 考虑两个矩阵 a rand N 3 b rand 3 N 我想要得到的是 b i a i 一个 3 3 矩阵 在第三维中串联所有i 因此 对于上面的示例 结果应该是 3 3 N 矩阵
  • 如何在 Eloquent 中检查行是否被软删除?

    在 Laravel 5 1 中 有没有一种好方法来检查雄辩的模型对象是否已被软删除 我不是在谈论选择数据 而是一旦我有了对象 例如Thing withTrashed gt find id 到目前为止我能看到的唯一方法是 if thing g
  • 证书验证失败:无法获取本地颁发者证书

    我正在尝试使用 python 从网络获取数据 我为其导入了 urllib request 包 但在执行时出现错误 certificate verify failed unable to get local issuer certificat
  • 在共享 x 轴的子图上绘制时 x 刻度消失[重复]

    这个问题在这里已经有答案了 当我尝试在同一个子图上绘制一条线和一个区域时 会发生这种情况 我发现我的 x 刻度在我调用 ay ax twinx 并在 ay 上绘图后消失了 这是导致此错误的我的代码 fig axes plt subplots
  • 将react-hooks-testing-library与jest.spyOn一起使用 - 不调用间谍

    我在设置单元测试以确定是否使用正确的参数调用函数时遇到问题 useAHook返回函数foo它调用函数bar 代码看起来像这样 myModule js export const useAHook arg1 arg2 gt const foo
  • Android:RES 目录中除 ic_ 之外的文件前缀标准?

    有人知道 RES 目录中是否有我们需要使用 或建议使用 的标准前缀列表 即 Android 建议使用 ic 作为图标 这很棒 我正在遵循这一点 但是徽标 按钮图像 导航图像等呢 我真的很想知道是否存在其他人以及其他人都在使用什么 提前致谢
  • WPF Multitrigger.ExitActions 将覆盖正常触发器

    我有一个无法解决的问题 所以我请她寻求帮助 这是导致我出现问题的代码的一部分
  • 每个基于 WebKit 的浏览器都会使使用 Omniture 的网站崩溃。为什么?

    其实 更准确的说法是 Every基于 WebKit 的浏览器崩溃http m allrecipes com http m allrecipes com 但仅在一个三星 Continuum SCH i400 http www samsung
  • HTML5 画布以一定角度绘制图像

    我正在尝试动画
  • 类似于浏览器的 async_hooks 之类的东西?

    我正在尝试调试在浏览器上下文中运行的一些 第三方 代码 并且我想跟踪所有下游异步函数调用 几乎完全相同async hooks为nodejs提供 本质上 类似https github com mafintosh why is node run
  • putText 用于 UTF-8 字符 (C++)

    我正在使用 putText OpenCV 方法在图像上写入文本 但它仅适用于 ASCII 字符 我需要打印诸如 之类的字符 有人可以帮忙吗 很遗憾 cv putText 仅支持 ASCII 有一个打开错误报告 http www code o
  • 跨多个场景使用 AVAudioPlayer Swift 并能够调节音量

    您好 我想知道是否有一种方法可以在多个场景中使用 AVAudioPlayer 并更改音量 我目前将其放置在我的 gameViewController 中 它是我的应用程序所有场景的控制器 override func viewDidAppea
  • Rails 关联方法如何工作?

    Rails 关联方法如何工作 让我们考虑这个例子 class User lt ActiveRecord Base has many articles end class Article lt ActiveRecord Base belong