如何使嵌套表单与Rails中的向导一起使用?

时间:2019-03-10 16:34:19

标签: ruby-on-rails wizard

我有一个向导,该向导允许用户选择出价(在步骤show中),然后希望他们提供一个地址(在步骤confirmation中)。除非同时添加了事务和地址信息,否则我希望没有任何东西可以持久保存在数据库中,因此将此功能放入向导很有意义。这比我想象的要困难得多,因为我不确定如何从其他来源收集到我收集的向导以接受另一个模型的嵌套属性。如果您看下面的向导代码,您会发现我已经做了 some 次尝试(这只是导致了一些uninitialized constant Transaction::Address错误),我只是...没有得到我想要的是。我不需要确切的解决方案,但是如果您有任何建议,我将不胜感激。

我的模型关联如下:

class User < ApplicationRecord
 has_many :addresses
 has_many :items
 has_many :transactions
end

class Item < ApplicationRecord
 belongs_to :user
 belongs_to :address, foreign_key: :address_id
 has_many :transactions
 accepts_nested_attributes_for :address
end

class Transaction < ApplicationRecord
 belongs_to :user
 belongs_to :item
 belongs_to :address
 accepts_nested_attributes_for :address
end

class Address < ActiveRecord::Base
 belongs_to :user, foreign_key: :user_id
 has_many :items
 has_many :transactions
end

我正在使用的向导如下:

module Wizard
 module Transaction
  STEPS = %w(show confirmation).freeze

  class Base
   include ActiveModel::Model
   attr_accessor :transaction
   #do i need an attr_accessor :address?
   delegate *::Transaction.attribute_names.map { |attr| [attr, "#{attr}="] }.flatten, to: :transaction
  # delegate *::Address.attribute_names.map { |attr| [attr, "#{attr}="] }.flatten, to: :address
  #address is a child of transaction, and i need to collect its attributes in the final step. do i set that up here, or in the final step?

   def initialize(transaction_attributes)
    @transaction = ::Transaction.new(transaction_attributes)
    # @address = ::Address.new(address_attributes)
   end
  end

  class Show < Base
   validates :sender_id, :recipient_id, :item_id, :sender_agreement, presence: true
   validates :amount, presence: true, numericality: { greater_than: 0 }
  end

  class Confirmation < Show

  end
 end
end

我的控制器如下:

class TransactionWizardsController < ApplicationController
 include TransactionWizard
 def confirm
  current_step = params[:current_step]
  @item = Item.friendly.find(params[:item_id])
  @transaction_wizard = wizard_transaction_for_step(current_step)
  @transaction_wizard.transaction.attributes = address_params
  session[:transaction_attributes] = @transaction_wizard.transaction.attributes

  if @transaction_wizard.valid?
   next_step = wizard_transaction_next_step(current_step)
   create and return unless next_step

   redirect_to action: next_step
  else
   redirect_to action: current_step
  end
 end

 def address_params
  params.require(:transaction_wizard).permit(addresses: [:name, :street, :street_2, :state, :zip_code])
 end
end

我的路线如下:

resources :items, path: 'art' do
 resource :transaction_wizard, only: [:new, :create], path: "bid" do
  get :confirmation
  post :add_to
  post :confirm
 end
end

我的confirmation视图中的表单如下:

<%= form_for @transaction_wizard, as: :transaction_wizard, url: confirm_item_transaction_wizard_path(@item) do |f| %>
  <%= f.fields_for @address do |address| %>
   <%= address.label "Full name" %>
   <%= address.text_field :name, placeholder: "Your full name", autofocus: true %>
   <%= address.label "Street address" %>
   <%= address.text_field :street, placeholder: "Your street address" %>

   <%= address.label "Apt" %>
   <%= address.text_field :street_2, placeholder: "Your apt or suite number" %>

   <%= address.label "State" %>
   <%= address.select :state, options_for_select(states_list), {prompt: 'State'}, class: 'ui selection dropdown' %>

   <%= address.label "Zip code" %>
   <%= address.text_field :zip_code, placeholder: "Your zip code" %>

  <% end %>
  <%= hidden_field_tag :current_step, 'confirmation' %>
  <%= f.submit "Complete offer" %>
<% end %>

0 个答案:

没有答案