【问题标题】:Rails checkbox checked updates shipping address while using form object pattern使用表单对象模式时,Rails 复选框选中更新送货地址
【发布时间】:2019-01-24 01:35:25
【问题描述】:

所以我有一个表单,我试图让用户将文本从帐单复制到送货地址。不幸的是,目前它会自动将帐单地址保存在送货地址中。

我的表单如下所示(尽管因大量字段而被截断):

=form_for @customer, url: create_customer_path, html: {class: 'new-customer} do |f|
 .row
  .col-md-4
   = f.label :first_name
  .col-md-8
   = f.text_field :first_name, class: 'form-control', required:true
 .row
  .col-md-4
   = f.label :billing_address1
  .col-md-8
   = f.text_field :billing_address1, class: 'form-control', required:true
 .row
  .col-md-12
   = f.check_box :shipping_is_billing
   = f.label :shipping_is_billing, 'Same as billing address'
 .row
  .col-md-4
   = f.label :shipping_address1
  .col-md-8
   = f.text_field :shipping_address1

客户控制器

class CustomersController < ApplicationController

  def new
    @customer = CustomerForm.new
  end

  def create
    @customer = CustomerForm.new(customer_params)
    if @customer.save
      redirect_to customer_success_path
    else
      render 'new'
    end
  end

  private

  def customer_params
    params.require(:customer_form).permit!.tap do |p|
      p[:captcha_response] = params['g-recaptcha-response']
    end
  end

end

CustomerForm(针对大量字段截断)

class CustomerForm
  include ActiveModel::Model

  CUSTOMER_ATTRS = %w[
    first_name
  ].freeze

  ADDRESS_ATTRS = %w[
    address1 address2 city state zip
  ].freeze

  attr_accessor(*CUSTOMER_ATTRS)
  attr_accessor(*ADDRESS_ATTRS.map { |attr| 'billing_' + attr })
  attr_accessor(*ADDRESS_ATTRS.map { |attr| 'shipping_' + attr })
  attr_accessor :confirm_email, :captcha_response, :shipping_is_billing

  validates :first_name, presence: true

  validates :billing_address1, presence: true

  validates :shipping_address1, presence: true, unless: :shipping_is_billing

  def save
    return false unless valid?
    persist!
  end

  private

  def captcha_passes
    captcha = Captcha.new
    return if captcha.valid?(captcha_response)
    errors.add(:captcha_response, 'is invalid')
  end

  def persist!
    customer = Customer.new(attrs_for_customer)
    customer.billing_address = CustomerAddress.new(attrs_for_address('billing_'))
    customer.shipping_address = CustomerAddress.new(
  attrs_for_address(shipping_is_billing ? 'billing_' : 'shipping_')
)
    customer.save!
    customer
  end

  def attrs_for_customer
    Hash[
      CUSTOMER_ATTRS.map { |attr| [attr, send(attr)] }
    ]
  end

  def attrs_for_address(prefix)
    Hash[
      ADDRESS_ATTRS.map { |attr| [attr, send(prefix + attr.to_s)] }
    ]
  end
end

JS

app.newCustomer = () => {
  function init() {
    let check = document.querySelector('#customer_form_shipping_is_billing')
    check.addEventListener('change', toggledUseBilling)
  }

  let toggledUseBilling = event => {
    shippingFields().forEach(field => {
      if(event.target.checked) {
        field.value = null;
        field.removeAttribute('required');
        field.setAttribute('disabled', true);
      } else {
        field.setAttribute('required', true);
        field.removeAttribute('disabled');
      }
    })
  }

  let shippingFields = () => {
    let selectors = [
      '#customer_form_shipping_address1',
      '#customer_form_shipping_address2',
      '#customer_form_shipping_city',
      '#customer_form_shipping_state',
      '#customer_form_shipping_zip',
    ]
    return document.querySelectorAll(selectors.join(', '));
  }

  return init();
}

坚持下!方法 我在复选框上使用三元运算符来确定要计费/发货的地址的属性。但它看起来并没有真正起作用。如何从表单中获取被标记的复选框?

以下是我尝试过的事情:

  • 已将 = f.check_box :shipping_is_billing 转换为 =check_box_tag :shipping_is_billing。然后我必须更新我的 JS 以确保我抓住了正确的复选框。这会存储运输数据,但检查时不会复制业务数据。
  • 已尝试将 attrs_for_address(shipping_is_billing ? 'billing_' : 'shipping_') 切换到 attrs_for_address(shipping_is_billing ? 'shipping_' : 'billing_')。如果我使用 check_box,这会将数据填充到运输,但复选框变得无效。
  • 在 check_box_tag 周围放置一个 form_tag 但这实际上去掉了复选框
  • 将 check_box 更改为 check_box_tag,更新了我的 JS 以在复选框上查找正确的 ID。如果输入,可以保存送货地址,但如果选中该框,则它不应用帐单地址,并且我收到提示送货地址不能为空

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    在持久化中做了一个 binding.pry!方法。看起来 shipping_is_billing 正在拉动一根正在触及真实的字符串。改为

    customer.shipping_address = CustomerAddress.new(
      attrs_for_address(shipping_is_billing == "1" ? 'billing_' : 'shipping_')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-06
      • 1970-01-01
      • 2022-01-21
      • 2017-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多