【问题标题】:How can I change serialized data using the best_in_place gem?如何使用 best_in_place gem 更改序列化数据?
【发布时间】:2014-02-12 18:00:42
【问题描述】:

我有一个带有序列化数据的模型,我想使用 best_in_place gem 编辑这些数据。使用 best_in_place gem 时,默认情况下这是不可能的。如何做到这一点?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 serialization best-in-place


    【解决方案1】:

    可以通过扩展method_missingrespond_to_missing?将请求转发到序列化数据来完成。假设您在data 中有序列化的Hash。例如,在包含序列化数据的类中,您可以使用以下代码:

    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 %>
    

    您不需要更改其余代码。

    【讨论】:

    • 谢谢你。非关联数组/哈希呢?对于没有键的数组是否有可能有类似的东西?这是我的问题:stackoverflow.com/questions/28415176/… 谢谢!
    • 查看编辑添加了关于如何将其用于数组的扩展
    • 非常感谢您的帮助!但是它不起作用,我在尝试更新值时在控制台中收到 Unpermitted_pa​​rameters: data_0 。我想这与强大的参数有关。与此同时,我正在切换回旧方式(使用输入)。
    • 惊人的答案,需要注意的两件事。我必须将 column_number 更改为 keydef data_setter(key, value) 更改为 def data_setter=(key, value) 才能正常工作!
    猜你喜欢
    • 2014-06-23
    • 2012-01-19
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多