0

失敗我有一個多態關聯用戶模式的地址模式Rails 3中嵌套屬性創建一個多態模型AssociationTypeMismatch

class User < ActiveRecord::Base 
    attr_accessible :addresses, :billing_addresses, :shipping_addresses, :shipping_same_as_billing 

    has_many :addresses, dependent: :destroy 

    has_many :billing_addresses, class_name: Address, conditions: ['type = ?', :billing] 
    has_many :shipping_addresses, class_name: Address, conditions: ['type = ?', :shipping] 
    accepts_nested_attributes_for :addresses 
#... 
end 

class Address < ActiveRecord::Base 
    belongs_to :user, polymorphic: true 
    validates_presence_of :line1, :city, :state, :zip 
    attr_accessible :line1, :line2, :city, :state, :zip, :type 
#... 
end 

我的形式:(有趣的部分是地址塊)

= form_tag '/subscriptions', class: 'form-horizontal', id: "new_order" do |f| 
    -if current_user.andand.stripe_customer_id.blank? 
     = field_set_tag("Billing Information") do 
     =simple_fields_for :creditcard do |cc| 
      = cc.input :card_number, hint: "test cc: 4242424242424242", :wrapper => :append do 
      = cc.input_field :card_number, id: "card_number", class: "input-medium", 
         size: 20, name: "" 
      %div#cc_type_holder.cc_32.add-on{style:"position:absolute;width:35px"} 
       %div#cc_type.cc_32 
      = cc.input :cvc, input_html: { id: "cvc", class: "input-mini", 
      size: 4, name: ""}, label: "CVC", hint: "This 3 or 4-digit code is usually found on the back of your credit card" 
      = cc.input :expiration, as: :date, start_year: Date.today.year, 
      end_year: Date.today.year + 10, discard_day: true, 
      order: [:month, :year], input_html: { class: "input-medium", name: ""} 
     = simple_fields_for "user[billing_addresses]" do |billing_address| 
      = billing_address.hidden_field :type, input_html: { value: "billing"} 
      = billing_address.input :line1, input_html: { class: "input-medium"} 
      = billing_address.input :line2, required: false, input_html: { class: "input-medium"} 
      = billing_address.input :city, input_html: { class: "input-medium"} 
      = billing_address.input :state, input_html: { class: "input-medium"} 
      = billing_address.input :zip, input_html: { class: "input-medium"} 
    -if current_user.blank? 
     = field_set_tag("User Information") do 
     = simple_fields_for :user do |users_post| 
      = users_post.input :email, input_html: { value: session[:email], type: "email", 
      placeholder: 'user[email protected]', class: "input-medium" } 
      = users_post.input :password, input_html: { class: "input-medium" } 
    = field_set_tag("Shipping Information") do 
     = simple_fields_for "user[shipping_addresses]" do |shipping_address| 
     = shipping_address.input :shipping_same_as_billing, as: :boolean, input_html: {checked: true, id: 'shipping-same-as-billing'} 
     %div#shipping-form 
      = shipping_address.hidden_field :type, input_html: { value: "shipping"} 
      = shipping_address.input :line1, input_html: { class: "input-medium"} 
      = shipping_address.input :line2, required: false, input_html: { class: "input-medium"} 
      = shipping_address.input :city, input_html: { class: "input-medium"} 
      = shipping_address.input :state, input_html: { class: "input-medium"} 
      = shipping_address.input :zip, input_html: { class: "input-medium"} 

     #stripe_error 
     .form-actions 
     = submit_tag t(".subscription.submit"), class: 'btn btn-success' 

發帖時我收到此錯誤形式:

ActiveRecord::AssociationTypeMismatch (Address(#70101930814600) expected, got Array(#70101927961780)):

我讀另一篇文章提到了試圖改變

config.cache_classes = true 

這並沒有做任何改變,我得到了同樣的錯誤。我真的不想手動建立關聯。看起來像ActiveRecord可以處理這個,我只是想念一些東西。

--edited徵求意見如下

Parameters: {"utf8"=>"✓", "authenticity_token"=>"HigNtHH08ER1S6p3xMUPlreWMuHngjo5S8z74jeqsO0=", "creditcard"=>{"expiration(3i)"=>"1"}, "user"=>{"billing_addresses"=>{"type"=>"", "line1"=>"1653 Main", "line2"=>"", "city"=>"Redwood City", "state"=>"California", "zip"=>"94061"}, "email"=>"[email protected]", "password"=>"[FILTERED]", "shipping_addresses"=>{"shipping_same_as_billing"=>"0", "type"=>"", "line1"=>"1653 Main", "line2"=>"", "city"=>"Redwood City", "state"=>"California", "zip"=>"94061"}}, "stripeToken"=>"[FILTERED]"} 

這些都是我送的PARAMS。我只是在調試控制器現在:

Rails.logger.debug params['user']['billing_addresses'] 
Rails.logger.debug params['user']['shipping_addresses'] 
u = User.new(params["user"]) 
Rails.logger.debug u 

{"type"=>"", "line1"=>"1653 Main", "line2"=>"", "city"=>"Redwood City", "state"=>"California", "zip"=>"94061"} 
{"shipping_same_as_billing"=>"0", "type"=>"", "line1"=>"1653 Main", "line2"=>"", "city"=>"Redwood City", "state"=>"California", "zip"=>"94061"} 

我看不到數組現在從哪裏來。除非ActiveRecord的走的是shipping_addressesbilling_addresses,並把它們當作一組地址...

+0

在我更新的答案看看,並採取讀,我還提供 – David

回答

0

我相信你的模型用戶需要的accepts_nested_attributes_for所以要儘量添加以下到您的user.rb

accepts_nested_attributes_for :addresses 
    accepts_nested_attributes_for :billing_addresses 
    accepts_nested_attributes_for :shipping_addresses 

進一步就此,您得到的錯誤:

ActiveRecord::AssociationTypeMismatch (Address(#70101930814600) expected, got Array(#70101927961780))

這是錯誤通常會在分配給對象的類型不正確時引發。所以打破這個錯誤。看來你的對象Address得到了錯誤的類型,但得到了一個數組。當你不應該餵食某個陣列的時候。

另一個關鍵注意事項:多態關聯通過使用foriegn關鍵字中的類型列來指定相關記錄。你需要一個你可以指定它的列。因此,一個例子是讓你具備以下條件:

class User < ActiveRecord::Base 
     attr_accessible :addresses, :billing_addresses, :shipping_addresses, 
    :shipping_same_as_billing 

     #Before  
     #has_many :addresses, dependent: :destroy 

     #After 
     has_many :addresses, :as => user, dependent => :destroy 

    end 

延伸閱讀:Polymorphic Associations

+0

感謝大衛的鏈接。我最終將整個功能重構成更簡單的東西。 – webdevtom