【问题标题】:editing form for serialized model序列化模型的编辑表格
【发布时间】:2013-12-27 20:09:55
【问题描述】:

我有模型 Info.rb 用于保存所有展览和比赛的信息

class Info < ActiveRecord::Base

  serialize :exhibition, Array
  serialize :contest, Array

end

我希望有编辑更新和添加新元素到展览和竞赛数组的能力。这是我的 info_controller.rb

class Admin::InfoController < ApplicationController

 before_action :find_info, only: [:edit, :update]

 def index
   @info = Info.all
 end

 def edit

 end

 def update
   @info.update_attributes(info_params)
   redirect_to admin_info_index_path
 end

 private

   def find_info
     @info = Info.first
   end

   def info_params
     params.require(:info).permit({:contest => []}, {:exhibition => []})     
   end

end

我不知道如何为数组中的每个元素创建带有单个字段的正确编辑表单。 将不胜感激。

【问题讨论】:

  • 如果你想从你的输入字段中创建一个数组,你需要用某种模式分割它。

标签: ruby-on-rails forms serialization ruby-on-rails-4 simple-form


【解决方案1】:

在您的模型中,您可以从序列化哈希或数组的键中动态分配属性。我已经做了类似的事情,所以我正在修改我的代码以获取下面的几个示例。基本上,通过动态创建虚拟属性,使用像 Formtastic 这样的 DSL 变得更加容易。

使用序列化数组:

 class Info < ActiveRecord::Base

   serialize :exhibition, Array
   serialize :contest, Array

   after_initialize :explode_exhibition
   after_initialize :explode_contest

   before_save :implode_exhibition
   before_save :implode_contest

   private 

   def explode_exhibition()
       exhibition.each_with_index do |v,i|
            self.class.send(:attr_accessor, "@exhibition_#{i}")
            self.instance_variable_set("@exhibition_#{i}", v)
       end
   end

   def explode_contest()
       contest.each_with_index do |v,i|
            self.class.send(:attr_accessor, "@contest_#{i}")
            self.instance_variable_set("@contest_#{i}", v)
       end
   end


   def implode_exhibition()
      exhibition = []
      self.methods.grep(/exhibition_/).each do |method_name|
            exhibition << self.instance_variable_get("@#{method_name}", v)
      end
   end

   def implode_contest()
      contest = []
      self.methods.grep(/contest_/).each do |method_name|
            contest << self.instance_variable_get("@#{method_name}", v)
      end
   end

 end

使用序列化哈希:

 class Info < ActiveRecord::Base

   serialize :exhibition, Hash
   serialize :contest, Hash

   after_initialize :explode_exhibition
   after_initialize :explode_contest

   before_save :implode_exhibition
   before_save :implode_contest

   private 

   def explode_exhibition()
       exhibition.each do |k,v|
            self.class.send(:attr_accessor, "@exhibition_#{k}")
            self.instance_variable_set("@exhibition_#{k}", v)
       end
   end

   def explode_contest()
       contest.each do |k,v|
            self.class.send(:attr_accessor, "@contest_#{k}")
            self.instance_variable_set("@contest_#{k}", v)
       end
   end


   def implode_exhibition()
      exhibition.each do |k,v|
            exhibition[k] = self.instance_variable_get("@exhibition_#{k}", v)
       end
   end

   def implode_contest()
      contest.each do |k,v|
            contest[k] = self.instance_variable_get("@contest_#{k}", v)
       end
   end

 end

然后在 Formtastic 中,您可以访问属性并为每个虚拟属性动态构建表单。注意正则表达式,可以使用一些迭代,因为它目前只会匹配 self.exhibition_0 到 self.exhibition_9,但它也排除了任何 setter 方法,因为它不匹配 self.exhibition_0=

 f.object.methods.grep(/^exhibition_.*?(?<!=)$/).each do |method_name|
    f.input  method_name
  end

我还没有完全测试过这个经过修改的代码,但其中大部分是在我自己的几个类中工作的。此外,可能还需要动态创建 setter 方法。让我测试一下,然后改进这个想法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 2017-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    相关资源
    最近更新 更多