如何通过反射获得activerecord关联

Mat*_*ggs 54 ruby reflection activerecord

对于普通列,您可以通过columns类方法获取它们.但是,如果foreign_key在关系方法中设置了选项,则可以将关联命名为完全不同的名称.例如,给定

class Post
  has_many :comments, :foreign_key => :message_id # this is a contrived example
end
Run Code Online (Sandbox Code Playgroud)

如果我这样做Post.column_names我可以得到message_id,但有没有办法得到comments

mik*_*kej 86

Model.reflections提供有关模型关联的信息.它是Hash关联名称的关键字.例如

Post.reflections.keys # => ["comments"]
Run Code Online (Sandbox Code Playgroud)

以下是可用于访问的一些信息的示例:

Post.reflections["comments"].table_name # => "comments"
Post.reflections["comments"].macro # => :has_many
Post.reflections["comments"].foreign_key # => "message_id"
Run Code Online (Sandbox Code Playgroud)

注意:此答案已更新,以涵盖基于MCB答案的Rails 4.2 和以下评论.在早期版本的Rails中,foreign_key使用primary_key_name反向访问反射,并且反射的键可以是符号而不是字符串,具体取决于如何定义关联,:comments而不是"comments".

  • 我们,反思只是返回哈希,而不是HashWithIndifferentAccess.因此.reflections哈希的键将是符号或字符串,具体取决于它在模型定义中的含义.这让我误以为它会是或者. (3认同)

MCB*_*MCB 21

对于Rails 4中的未来Google员工,答案现在是:

Post.reflections[:comments].foreign_key # => "message_id"
Run Code Online (Sandbox Code Playgroud)

取自这里:https://stackoverflow.com/a/15364743/2167965

编辑:

reflections,从4.2开始,现在采用字符串而不是符号,这是一个有趣的错误追踪.如果你想继续使用符号,你应该切换到reflect_on_association(:assoc_name).另外还要注意reflections的是公共API,它会继续报告像HABTM这样的东西,尽管它们都有很多内容.Rails实际上正在使用的反射现在_reflections

  • 非常感谢.我是未来的Google员工.:) (12认同)