簡體   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