【问题标题】:Ruby send method with rails associations带有 Rails 关联的 Ruby 发送方法
【发布时间】:2011-11-15 16:00:49
【问题描述】:

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

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 Commentcomment.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​​ 开发人员,但我正在努力。

P.S 上面的代码可能无法正常工作,因为我没有使用 ruby​​/rails 进行测试,但希望你能理解这个概念。

干杯

【问题讨论】:

    标签: ruby ruby-on-rails-3 send dynamic-method


    【解决方案1】:

    第一个也是最肮脏的解决方案是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 表达式是多么容易出错。) - @查克

    【讨论】:

    • 您好,感谢您的快速回复。我认为我的方法会很丑:) 还在学习。任何意见,将不胜感激。不过,感谢您提供这些解决方案!
    • 注入可以更简洁地写成field.split('.').inject(model, :send)。我强烈反对eval 方式——不必要的evals 是另一种情况,您可以滑倒并允许任意代码执行,而且它们也很慢。 (另外,我很确定应该只是 eval("model.#{field}") — 你不想插入 model 的字符串值。又一个例子说明了eval 表达式是多么容易出错。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 2013-03-24
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多