繁体   English   中英

Rails:belongs_to 关联打破了多步形式

[英]Rails: belongs_to association breaks multistep form

我正在将旧版 Rails 应用程序从 3.2.5 更新到 Rails 7。在应用程序中,我有一个多步骤表单,它遵循Railscasts # 217 这意味着我有一个 Order 模型:

attr_writer :current_step

# Associations
  belongs_to :bill_to_land, class_name: "Land", foreign_key: :bill_to_land_id
  belongs_to :ship_to_land, class_name: "Land", foreign_key: :ship_to_land_id
  belongs_to :order_status
  belongs_to :shipping_service
  has_many :order_items
  has_many :products, through: :order_items

# Validations
  validates_presence_of :shipping_name, :if => lambda { |o| o.current_step == "shipping" }
  validates_presence_of :ship_to_land, if: -> { current_step == "shipping" }
  validates_presence_of :billing_name, :if => lambda { |o| o.current_step == "billing" }
  validates_presence_of :bill_to_land, if: -> { current_step == "billing" }

def current_step
  @current_step || steps.first
end

def steps
  %w[shipping billing confirmation]
end

def next_step
  self.current_step = steps[steps.index(current_step)+1]
end

def previous_step
  self.current_step = steps[steps.index(current_step)-1]
end

def first_step?
  current_step == steps.first
end

def last_step?
  current_step == steps.last
end

def all_valid?
  steps.all? do |step|
    self.current_step = step
    valid?
  end
end

在我的订单控制器中,我有类似的东西:

def new
  session[:order_params] ||= {}
  @order = Order.new(session[:order_params])
  @order.current_step = session[:order_step]
end

def create
  session[:order_params].deep_merge!(params[:order]) if params[:order]
  @order = Order.new(session[:order_params])
  @order.current_step = session[:order_step]
  if @order.valid?
    if params[:back_button]
      @order.previous_step
    elsif @order.last_step?
      @order.save if @order.all_valid?
    else
      @order.next_step
    end
    session[:order_step] = @order.current_step
  end
  if @order.new_record?
    render "new"
  else
    session[:order_step] = session[:order_params] = nil
    flash[:notice] = "Order saved!"
    redirect_to @order
  end
end

有这样的观点:

<% form_for @order, data: { turbo_confirm: 'Are you sure to order?' } do |f| %>
  <%= f.error_messages %>
  <%= render "#{@order.current_step}_step", :f => f %>
  <p><%= f.submit "Continue", data: { turbo: false } %></p>
  <p><%= f.submit "Back", :name => "back_button" unless @order.first_step?, data: { turbo: false } %></p>
<% end %>

这曾经在升级之前工作。 现在多步被破坏了,因为bill_to_land已经在第一步验证了。 我想问题不在于验证本身,而是所有的 belongs_to 关联都已经在表单的第一步进行了验证。 我可以通过注释掉if @order.valid? 在我的控制器中,但这会停用所有验证。

在升级过程中我必须对原始代码进行的唯一调整是在我的视图中添加data: { turbo: false }到提交标签。

有谁知道为什么这种多步骤的实现以前有效,为什么它停止工作以及我应该如何继续才能让它再次工作?

非常感谢您提前。

由于Rails 5.0版本默认需要belongs_to

您可以关闭此选项:

# config/application.rb
config.active_record.belongs_to_required_by_default = false

或添加optional: true到您的belongs_to关联:

belongs_to :bill_to_land, class_name: "Land", foreign_key: :bill_to_land_id, optional: true
belongs_to :ship_to_land, class_name: "Land", foreign_key: :ship_to_land_id, optional: true
belongs_to :order_status, optional: true
belongs_to :shipping_service, optional: true

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM