rails 关联方法如何工作?

编程入门 行业动态 更新时间:2024-10-26 16:24:08
本文介绍了rails 关联方法如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

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

How do rails association methods work? Lets consider this example

class User < ActiveRecord::Base has_many :articles end class Article < ActiveRecord::Base belongs_to :user end

现在我可以做类似的事情

Now I can do something like

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

这会为我获取属于该用户的文章.到目前为止一切顺利.

This fetches me articles belonging to that user. So far so good.

现在,我可以继续在某些条件下对这些文章进行查找.

Now further I can go ahead and do a find on these articles with some conditions.

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

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

Or simply declare and associations method like

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

@user.articles.of_sector(3)

现在我的问题是,这个 find 如何在使用关联方法获取的 ActiveRecord 对象数组上工作?因为如果我们实现我们自己的名为 articles 的 User 实例方法,并编写我们自己的实现,该方法为我们提供与关联方法完全相同的结果,fetch 数组上的 findActiveRecord 对象将无法工作.

Now my question is, how does this find work on the array of ActiveRecord objects fetched using the association method? Because if we implement our own User instance method called articles and write our own implementation that gives us the exact same results as that of the association method, the find on the fetch array of ActiveRecord objects wont work.

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

My guess is that the association methods attach certain properties to the array of fetched objects that enables further querying using find and other ActiveRecord methods. What is the sequence of code execution in this this case? How could I validate this?

推荐答案

它的实际工作原理是关联对象是一个代理对象".具体的类是AssociationProxy.如果您查看该文件的第 52 行,您会看到:

How it actually works is that the association object is a "proxy object". The specific class is AssociationProxy. If you look at line 52 of that file, you'll see:

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

通过这样做,像 class 这样的方法不再存在于这个对象上.所以如果你在这个对象上调用 class ,你会丢失方法.因此,为将方法调用转发到目标"的代理对象实现了一个 method_missing:

By doing this, methods like class no longer exist on this object. So if you call class on this object, you'll get method missing. So, there a method_missing implemented for the proxy object that forwards the method call to the "target":

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,但是你再也看不到了.

The target is an Array, so when you call class on this object, it says it's an Array, but that's just because the target is an Array, the actual class is an AssociationProxy, but you can't see that anymore.

因此,您添加的所有方法,例如 of_sector,都会添加到关联代理中,因此它们会被直接调用.[] 和 class 之类的方法没有在关联代理上定义,所以它们被发送到目标,这是一个数组.

So all the methods that you add, such as of_sector, get added to the association proxy, so they get called directly. Methods like [] and class aren't defined on the association proxy, so they get sent to the target, which is an array.

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

To help you see how this is happening, add this to line 217 of that file in your local copy of association_proxy.rb:

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

如果你不知道那个文件在哪里,命令 gem which 'active_record/associations/association_proxy' 会告诉你.现在,当您在 AssociationProxy 上调用 class 时,您将看到一条日志消息,告诉您它正在将其发送到目标,这应该更清楚发生了什么.这是 Rails 2.3.2 的全部内容,可能会在其他版本中更改.

If you don't know where that file is, the command gem which 'active_record/associations/association_proxy' will tell you. Now when you call class on a AssociationProxy, you will see a log message telling you it is sending that to the target, which should make it clearer what is happening. This is all for Rails 2.3.2 and could change in other versions.

更多推荐

rails 关联方法如何工作?

本文发布于:2023-11-05 21:17:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1561888.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:方法   工作   rails

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!