我有一个向导,该向导允许用户选择出价(在步骤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 %>