0

我一直在做一个可排序的表模块的事情。我知道有些可能存在,但我想自己获得经验。我有这样的想法:

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

这适用于标题和正文,但是当涉及到Last Comment错误comment.last.title时。我试过做Post.send("comments.last.title")但是说NoMethodError: undefined method 'comments.last.title' for #<Post:0x0000010331d220>

我知道我可以做到Post.send("comments").send("last").send("title")并且有效,但我想不出如何通过获取字段并拆分 on 来动态地做到这一点。然后链接发送。谁能给我建议如何做到这一点?如果我这样做也完全错误,那么请说或指出我做类似事情的代码方向。我不是专家 ruby​​ 开发人员,但我正在尝试。

PS 上面的代码可能不起作用,因为我不在一台带有 ruby​​/rails 的计算机上进行测试,但希望你能理解这个概念。

干杯

4

1 回答 1

2

第一个也是最肮脏的解决方案是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

附言

而且你的设计很丑

编辑

注入可以更简洁地写为field.split('.').inject(model, :send). 而且我强烈反对这种eval方式 - 不必要evals的情况是您可以滑倒并允许任意代码执行,而且它们也很慢。(另外,我很确定应该只是eval("model.#{field}")——你不想插入 的字符串值model。又一个例子说明了表达式是多么容易eval出错。)——@Chuck

于 2011-09-12T20:50:48.647 回答