ruby-on-rails 如何从我的text_field表单助手中强制使用正确的哈希访问语法?

7eumitmz  于 2023-03-31  发布在  Ruby
关注(0)|答案(1)|浏览(88)

我正在使用Mongo进行一个Rails项目。我在我的视图表单帮助程序中遇到了一个问题,即(我不确定是通过Rails还是Mongoid访问)我试图访问模型上的Hash字段中的值,但我得到了一个未定义的方法错误,因为它试图使用点表示法而不是括号表示法访问哈希值。
模型:

class AgencySetting
  include Mongoid::Document
  include Mongoid::Timestamps

  field :uuid,            type: String
  field :mailing_address, type: Hash
  field :service_address, type: Hash
  field :active,          type: Boolean, default: true

  embeds_many :contracts

  validates :uuid, presence: true, uniqueness: true
end

形式(这可能不是处理Hash属性字段的理想方式,还有另一个f.fields_for附加到service_address,为了简洁起见,我排除了它):

= form_with model: @agency_setting, url: agency_setting_url, method: :post do |f|

        = f.fields_for :mailing_address, @agency_setting.mailing_address do |m_fields|
          = m_fields.text_field :line_1, class: 'form-control my-1', placeholder: 'Contract street line one'
          = m_fields.text_field :line_2, class: 'form-control my-1', placeholder: 'Contract street line two'
          = m_fields.text_field :city, class: 'form-control my-1', placeholder: 'Contract city'
          = m_fields.text_field :state, class: 'form-control my-1', placeholder: 'Contract state'
          = m_fields.text_field :zip, class: 'form-control my-1', placeholder: 'Contract zip'

        = f.submit 'Save settings', class: 'btn btn-primary mt-2'

它在m_fields的第一行抛出错误,具体来说,它给出undefined method 'line_1' for {"line_1"=>"123", "line_2"=>"123", "city"=>"123", "state"=>"123", "zip"=>"123"}:BSON::Document。显然,这是因为它试图使用mailing_address.line_1而不是mailing_address[:line_1]访问mailing_address,后者在控制台中运行良好。是否可以强制帮助程序使用后一种语法?

vaj7vani

vaj7vani1#

有没有可能强制helper使用后一种语法?
否。但您可以手动提供值:

= form_with model: @agency_setting, url: agency_setting_url, method: :post do |f|
  = f.fields_for :mailing_address, @agency_setting.mailing_address do |m_fields|
    = m_fields.text_field :line_1, 
                          class: 'form-control my-1', 
                          placeholder: 'Contract street line one',
                          value: m_fields.object[:line_1]

或者你可以将Hash转换成OpenStruct:

= form_with model: @agency_setting, url: agency_setting_url, method: :post do |f|
  = f.fields_for :mailing_address, OpenStruct.new(@agency_setting.mailing_address) do |m_fields|
    = m_fields.text_field :line_1, 
                          class: 'form-control my-1', 
                          placeholder: 'Contract street line one'
    # ...

但这确实回避了一个问题,为什么你要搬起石头砸自己的脚,而不是更好地建模你的数据。
一个二个一个一个
当涉及到添加验证和处理输入时,拥有一个实际的模型将使您的生活变得更加轻松。

相关问题