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

これはタイトルと本文には問題なく機能しますが、withitを取得する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を分割することによって動的にそれを行う方法を考えることはできません。次に、送信をチェーンします。誰かがこれを行う方法について私にアドバイスを与えることができますか?私がこれを完全に間違って行っている場合も、同様のことを行うコードの方向に私に言ってください。私は専門家のルビー開発者ではありませんが、努力しています。

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

PS

そしてあなたのデザインは醜いです

編集

インジェクトは、より簡潔にと書くことができますfield.split('.').inject(model, :send)。そして、私はそのeval方法を強くお勧めしません—不必要なのevalsは、あなたがスリップして任意のコードの実行を許可する可能性があるもう1つのケースであり、それらも遅いです。(また、そうあるべきだと確信していますeval("model.#{field}")—の文字列値を補間したくないのですmodel。式をすり抜けるのがいかに簡単かを示すもう1つの例ですeval。)– @Chuck

于 2011-09-12T20:50:48.647 に答える