使用simple_form添加自定义JSONB text_field标记

时间:2017-03-29 17:40:48

标签: ruby-on-rails ruby-on-rails-5 simple-form

我的Rails应用程序中的模型上有一个JSONB类型options列,我需要为每个表单手动提供JSONB嵌套参数。这就是为什么官方解决方案提议here不是一种选择。

所以我可能希望有类似的东西:

options[first_name], options[last_name]

表示一个实例,而另一个实例完全不同:

options[pet_dog], options[frank_sinatra]

我认为可以使用像

这样的东西来实现它
= f.text_field :options[pet_dog]

但它没有用。

2 个答案:

答案 0 :(得分:1)

你是如何实现jsonb列的?你有没有把它添加到模型中?

serialize :options, HashSerializer
store_accessor :options, :pet_dog, :pet_cat, :pet_cow

*请注意,HashSerializer是一个充当序列化程序的类,如下所示:

class HashSerializer
  def self.dump(hash)
    hash.to_json
  end

  def self.load(hash)
    (hash || {}).with_indifferent_access
  end
end

模型上的那两行允许你使用访问器(getter和setter)作为json / jsonb键。所以你可以这样做:

object = Model.new
object.pet_dog = 'Dog1'
object.pet_cat = 'Cat1'
object.options = {"pet_dog"=>"Dog1", "pet_cat"=>"Cat1"}

反过来,允许您将其用作表单字段:

f.text_field :pet_dog
f.text_field :pet_cat

不要忘记将strong_params方法中的属性列入白名单

你可以阅读Nando Vieira在这篇综合文章中的更多内容: http://nandovieira.com/using-postgresql-and-jsonb-with-ruby-on-rails

此外,如果你想要一个快捷方式,有一个宝石: https://github.com/devmynd/jsonb_accessor

答案 1 :(得分:0)

我的解决方案代码如下所示:

查看表单:

= f.simple_fields_for :options do |p|
  - @options.each do |o|
    = p.input o.name.to_sym, input_html: {value: o.default_value}

控制器

def new
  @options = Model.options
  ...
end

def create
  @job  = current_user.jobs.build(job_params)
end

...

def job_params
  params.require(:job_request).permit(
  ...
  options: get_options)
end

def get_options
  some_model.options.pluck(:name).map(&:to_sym)
end

这可能会对某人有所帮助。