我一直在努力解決這個問題,並嘗試了很多選擇,觀看了http://railscasts.com/episodes/26-hackers-love-mass-assignment?view=asciicast和http://railscasts.com/episodes/196-nested-model-form-part-1 Railscasts,並試用了Devise解決方案Github的頁面,但無法找到解決這個問題。使用Devise時不能批量分配關聯模型的受保護屬性
我正在使用Rails 3.2
我有一個用戶有很多地址。
用戶模型:
class User < ActiveRecord::Base
rolify
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :stripe_token, :coupon, :addresses_attributes
attr_accessor :stripe_token, :coupon
before_save :update_stripe
before_destroy :cancel_subscription
has_many :addresses
accepts_nested_attributes_for :addresses, :reject_if => :all_blank, :allow_destroy => true
def update_plan(role)
self.role_ids = []
self.add_role(role.name)
unless customer_id.nil?
customer = Stripe::Customer.retrieve(customer_id)
customer.update_subscription(:plan => role.name)
end
true
rescue Stripe::StripeError => e
logger.error "Stripe Error: " + e.message
errors.add :base, "Unable to update your subscription. #{e.message}."
false
end
def update_stripe
return if email.include?(ENV['ADMIN_EMAIL'])
return if email.include?('@example.com') and not Rails.env.production?
if customer_id.nil?
if !stripe_token.present?
raise "Stripe token not present. Can't create account."
end
if coupon.blank?
customer = Stripe::Customer.create(
:email => email,
:description => name,
:card => stripe_token,
:plan => roles.first.name
)
else
customer = Stripe::Customer.create(
:email => email,
:description => name,
:card => stripe_token,
:plan => roles.first.name,
:coupon => coupon
)
end
else
customer = Stripe::Customer.retrieve(customer_id)
if stripe_token.present?
customer.card = stripe_token
end
customer.email = email
customer.description = name
customer.save
end
self.last_4_digits = customer.cards.data.first["last4"]
self.customer_id = customer.id
self.stripe_token = nil
rescue Stripe::StripeError => e
logger.error "Stripe Error: " + e.message
errors.add :base, "#{e.message}."
self.stripe_token = nil
false
end
def cancel_subscription
unless customer_id.nil?
customer = Stripe::Customer.retrieve(customer_id)
unless customer.nil? or customer.respond_to?('deleted')
if customer.subscription.status == 'active'
customer.cancel_subscription
end
end
end
rescue Stripe::StripeError => e
logger.error "Stripe Error: " + e.message
errors.add :base, "Unable to cancel your subscription. #{e.message}."
false
end
def expire
UserMailer.expire_email(self).deliver
destroy
end
end
用戶控制器:
def new
@plan = params[:plan]
if @plan && ENV["ROLES"].include?(@plan) && @plan != "admin"
super
@user.addresses.build
else
redirect_to root_path, :notice => 'Please select a subscription plan below.'
end
end
地址模型;
class Address < ActiveRecord::Base
attr_accessible :country, :county, :first_line, :postcode, :second_line, :town_city
#validates :country, :user_id, :county, :first_line, :postcode, :town_city, presence: true
belongs_to :user
end
地址控制器:
class AddressesController < ApplicationController
def create
end
def update
end
end
在我看來,我嵌套的地址模式,使我可以創建一個用戶,並在一個犯規一舉地址:
<div class="intro2">
<% content_for :head do %>
<%= tag :meta, :name => "stripe-key", :content => STRIPE_PUBLIC_KEY %>
<% end %>
<div id="stripe_error" class="alert alert-error" style="display:none" >
</div>
<%= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:class => 'card_form form-vertical form-signin' }) do |f| %>
<%= link_to '<i class="icon-step-backward"></i>''back'.html_safe, root_path %>
<h2>Sign up</h2>
<h3><%= params[:plan].titleize if params[:plan] %> Subscription Plan</h3>
<%= hidden_field_tag 'plan', params[:plan] %>
<%= f.error_notification %>
<%= display_base_errors resource %>
<%= f.input :name, :autofocus => true %>
<%= f.input :email, :required => true %>
<%= f.input :password, :required => true %>
<%= f.input :password_confirmation, :required => true %>
<%= field_set_tag 'Customer Details' do %>
<%= f.fields_for :address do |builder| %>
<%= builder.label :first_line %>
<%= builder.text_field :first_line %>
<%= builder.label :second_line %>
<%= builder.text_field :second_line %>
<%= builder.label :town_city %>
<%= builder.text_field :town_city %>
<%= builder.label :county %>
<%= builder.text_field :county %>
<%= builder.label :postcode %>
<%= builder.text_field :postcode %>
<%= builder.label :country %>
<%= builder.text_field :country %>
<% end %>
<% end %>
<% if @user.stripe_token %>
<p>Credit card acceptance is pending.</p>
<% else %>
<div class="field">
<%= label_tag :card_number, "Credit Card Number" %>
<%= text_field_tag :card_number, nil, name: nil %>
</div>
<div class="field">
<%= label_tag :card_code, "Card Security Code (CVV)" %>
<%= text_field_tag :card_code, nil, name: nil %>
</div>
<div class="field">
<%= label_tag :card_month, "Card Expiration" %>
<%= select_month nil, {add_month_numbers: true}, {name: nil, id: "card_month"}%>
<%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+10}, {name: nil, id: "card_year"}%>
</div>
<div class="field">
<%= f.input :coupon, :label => 'Promotional Coupon (if any)' %>
</div>
<% end %>
<%= f.hidden_field :stripe_token %>
<%= f.button :submit, 'Sign up', :class => 'btn-primary' %>
<% end %>
</div>
錯誤信息我在瀏覽器中得到的是:
ActiveModel :: MassAssignmentSecurity :: Error at/users 不能大規模指派保護的屬性:地址
請求參數爲:
{"utf8"=>"✓", "authenticity_token"=>"+69wR2xYkBARu+JlsnizyF+0hrRUXo6Z+XGAipw98NY=", "plan"=>"silver", "user"=>{"name"=>"Bob", "email"=>"[email protected]", "password"=>"12345678", "password_confirmation"=>"12345678", "address"=>{"first_line"=>"7a Annette Road", "second_line"=>"Bob's Landing", "town_city"=>"London", "county"=>"Greater London", "postcode"=>"N76ET", "country"=>"UK"}, "coupon"=>"", "stripe_token"=>"tok_103NDO2KdYRHhGilKFAqsYaA"}, "action"=>"create", "controller"=>"registrations"}
由於設計Github的頁面上推薦我試圖把下面的我的應用程序控制器:
before_filter :configure_permitted_parameters, if: :devise_controller?
和
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:addresses_attributes) }
end
無濟於事。 (我也嘗試允許'地址'和'地址')/
任何解決方案真的很感激。 (順便說一下,如果你注意到其他代碼不是最佳的,那麼也很高興知道這一點 - 熱衷於選擇好習慣)。
感謝
嘗試'<%= f.fields_for:addresses do | builder | %>'而不是'<%= f.fields_for:address do | builder | %>'? – scaryguy
@scaryguy這樣做會導致地址字段不會顯示在您的控制器的視圖 – JRTurner1234
中,您還應該添加諸如'@ user.addresses.build'的東西 – scaryguy