Ruby发送方法与rails关联
我一直在搞乱制作可排序的表格模块的事情。 我知道有些可能存在,但我希望自己有这方面的经验。 我有这样想的想法:
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
comment.last.title
它会出错。 我已经尝试过Post.send("comments.last.title")
但是说NoMethodError: undefined method 'comments.last.title' for #
我知道我可以做Post.send("comments").send("last").send("title")
并且可以工作,但我无法想到如何通过获取字段和分割开来动态地做到这一点。 然后链接发送。 谁能给我建议如何做到这一点? 如果我这样做完全错了,那么请说或指向我做类似的代码的方向。 我不是专家ruby开发人员,但我正在努力。
PS上面的代码可能无法正常工作,因为我不在计算机上使用ruby / rails进行测试,但希望你能得到这个概念。
干杯
第一个也是最脏的解决方案是eval
fields.each do |column, field| data[column] = eval("#{model}.#{field}") end
下一个解决方案function更多
fields.each do |column, field| data[column] = field.split(".").inject(model){|obj, met| obj.send(met)} end
PS
你的设计很难看
编辑
注入可以更简洁地编写为field.split('.').inject(model, :send)
。 而且我强烈反对eval
方式 – 不必要的evals
是另一种情况,你可以滑倒并允许任意代码执行,而且它们也很慢。 (另外,我很确定应该只是eval("model.#{field}")
– 你不想插入model
的字符串值。另一个例子是如何轻松地使用eval
表达。) – @Chuck