具有rails关联的Ruby发送方法

具有rails关联的Ruby发送方法,ruby,ruby-on-rails-3,send,dynamic-method,Ruby,Ruby On Rails 3,Send,Dynamic Method,我一直在忙着做一个可排序的模块。我知道有些可能存在,但我希望自己能有这样的经验。我有这样的想法: SortedTable.new(ModelName, Hash_Of_Columns_And_Fields, ID) 范例 SortedTable.new(Post, {"Title" => "title", "Body" => "body", "Last Comment" => "comment.last.title"}, params[:id]) 我计划做一些类似的事情:

我一直在忙着做一个可排序的模块。我知道有些可能存在,但我希望自己能有这样的经验。我有这样的想法:

SortedTable.new(ModelName, Hash_Of_Columns_And_Fields, ID)
范例

SortedTable.new(Post, {"Title" => "title", "Body" => "body", "Last Comment" => "comment.last.title"}, params[:id])
我计划做一些类似的事情:

def initialize(model, fields, id)
  data = {}
  model = model.capitalize.constantize
  model.find(id)
  fields.each do |column, field|
    data[column] = model.send(field)
  end
end
这对标题和正文很有效,但当涉及到使用
Comment.Last.title
获取
Last Comment
时,它会出错。我曾经尝试过使用
Post.send(“comments.last.title”)
但是说
NoMethodError:undefined method“comments.last.title”for#

我知道我可以做
Post.send(“comments”).send(“last”).send(“title”)
,这很管用,但我想不出如何通过获取字段和拆分字段来动态实现这一点。然后链接发送。有人能给我一些建议吗?如果我做得完全错误,那么请告诉我或者告诉我做类似事情的代码的方向。我不是一个专业的ruby开发人员,但我正在努力

另外,上面的代码可能不起作用,因为我不是在一台使用ruby/rails进行测试的计算机上,但希望您能理解这个概念


干杯

第一个最肮脏的解决方案是
eval

fields.each do |column, field|
  data[column] = eval("#{model}.#{field}")
end
下一个解决方案更实用一些

fields.each do |column, field|
  data[column] = field.split(".").inject(model){|obj, met| obj.send(met)}
end
PS

你的设计很难看

编辑


注入可以更简洁地写成
field.split('..').inject(model,:send)
。我强烈反对使用
eval
方式-不必要的
eval
是另一种可能出现错误并允许任意代码执行的情况,而且执行速度也很慢。(另外,我很确定这应该是
eval(“model.#{field}”)
-你不想插入
model
的字符串值。这又是一个
eval
表达式容易出错的例子。)–@Chuck

嘿,谢谢你的快速回复。我觉得我的方法会很难看:)还在学习。如有任何建议,将不胜感激。不过,感谢您提供这些解决方案!注入可以更简洁地写成
field.split('..').inject(model,:send)
。我强烈反对使用
eval
方式-不必要的
eval
是另一种可能出现错误并允许任意代码执行的情况,而且执行速度也很慢。(另外,我很确定应该是
eval(“model.#{field}”)
-您不想插入
model
的字符串值。这又是一个
eval
表达式容易出错的例子。)