1

best_in_placeシリアル化されたデータを持つモデルがあり、 gemを使用してこのデータを編集したいと考えています。best_in_place ジェムを使用する場合、これはデフォルトでは不可能です。これはどのように行うことができますか?

4

1 に答える 1

4

これは、リクエストをシリアル化されたデータに拡張method_missingrespond_to_missing?て転送することで実行できます。Hashでシリアル化されているとしましょうdata。シリアル化されたデータを含むクラスでは、たとえば次のコードを使用できます。

def method_missing(method_name, *arguments, &block) # forewards the arguments to the correct methods
  if method_name.to_s =~ /data_(.+)\=/
    key = method_name.to_s.match(/data_(.+)=/)[1]
    self.send('data_setter=', key, arguments.first)
  elsif method_name.to_s =~ /data_(.+)/
    key = method_name.to_s.match(/data_(.+)/)[1]
    self.send('data_getter', column_number)
  else
    super
  end
end

def respond_to_missing?(method_name, include_private = false) # prevents giving UndefinedMethod error
  method_name.to_s.start_with?('data_') || super
end

def data_getter(key)
  self.data[key.to_i] if self.data.kind_of?(Array)
  self.data[key.to_sym] if self.data.kind_of?(Hash)
end

def data_setter(key, value)
  self.data[key.to_i] = value if self.data.kind_of?(Array)
  self.data[key.to_sym] = value if self.data.kind_of?(Hash)
  value # the method returns value because best_in_place sets the returned value as text
end

これで、getter object.data_name を使用して object.data[:name] にアクセスし、setter object.data_name="test" を使用して値を設定できます。ただし、これをbest_in_place機能させるには、リストに動的に追加する必要がありattr_accessibleます。これを行うには、 の動作を変更し、次のように編集できるメソッド名の配列でmass_assignment_authorizerオブジェクトが応答するようにする必要があります。accessable_methods

def accessable_methods # returns a list of all the methods that are responded dynamicly
  self.data.keys.map{|x| "data_#{x.to_s}".to_sym }
end

private
  def mass_assignment_authorizer(user) # adds the list to the accessible list.
    super + self.accessable_methods
  end

したがって、ビューで呼び出すことができます

  best_in_place @object, :data_name

@object.data[:name] のシリアル化されたデータを編集するには

// 属性名の代わりに要素インデックスを使用して、配列に対してこれを行うこともできます。

<% @object.data.count.times do |index| %>
  <%= best_in_place @object, "data_#{index}".to_sym %>
<% end %>

残りのコードを変更する必要はありません。

于 2014-01-22T15:25:29.767 に答える