如何使用 best_in_place gem 更改序列化数据? [英] How can I change serialized data using the best_in_place gem?
问题描述
我有一个包含序列化数据的模型,我想使用 best_in_place
gem 编辑此数据.使用 best_in_place gem 时,默认情况下这是不可能的.这怎么办?
I have a model with serialized data and I want to edit this data using the best_in_place
gem. This isn't possible by default when using the best_in_place gem. How can this be done?
推荐答案
可以通过扩展 method_missing
和 respond_to_missing?
将请求转发到序列化数据来实现.假设您在 data
中有序列化的 Hash
.例如,在包含序列化数据的类中,您可以使用以下代码:
It can be done by extending method_missing
and respond_to_missing?
to forward the requests to the serialized data. Lets say you have your serialized Hash
in data
. In the class that's containing the serialized data you can for example use this code:
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
的方法名称数组,这些方法名称应该允许像这样
Now you can access the object.data[:name] using the getter object.data_name and set value using the setter object.data_name="test". But to get this working using best_in_place
you need to dynamicly add it to the attr_accessible
list. To do this you need to change the behavior of the mass_assignment_authorizer
and make the object respond to accessable_methods
with an array of method names that should be allowed to be edited like this:
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
所以在视图中你现在可以调用
So in the View you can now call
best_in_place @object, :data_name
编辑@object.data[:name]的序列化数据
To edit the serialized data of @object.data[:name]
//您也可以使用元素索引而不是属性名称对数组执行此操作:
// You can also do this for an array using the element index instead of the attribute name:
<% @object.data.count.times do |index| %>
<%= best_in_place @object, "data_#{index}".to_sym %>
<% end %>
您无需更改其余代码.
这篇关于如何使用 best_in_place gem 更改序列化数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!