問題描述
創建關聯後,控制器中的 Ruby on rails NoMethodError (Ruby on rails NoMethodError in controller after create an association)
I have two models User and Promotion, an user can create has_many promotion and an promotion belong to user so :
promotion.rb
class Promotion < ActiveRecord::Base
belongs_to :user
belongs_to :good
validates :name, :presence => true
validates :title, :presence => true
validates :description, :presence => true
end
for the users i used devise so:
user.rb
class User < ActiveRecord::Base
has_many :promotions ,:foreign_key => "user_id",
:dependent => :destroy
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, :omniauth_providers => [:facebook]
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me,:provider,:uid,:address,:name,:surname,:supplier,:partita_iva,:state,
:gender ,:language,:bio,:work,:education
now when i want create a new promotions get this error
NoMethodError in PromotionsController#create undefined method `promotions' for nil:NilClass
this is the controller:
def create
@user = User.find_by_id(params[:user_id])
@promotion =@user.promotions.create(:params[:promotion])
redirect_to promotion_patch(@promotion)
respond_to do |format|
if @promotion.save
format.html { redirect_to @promotion, notice: 'Promotion was successfully created.' }
format.json { render json: @promotion, status: :created, location: @promotion }
else
format.html { render action: "new" }
format.json { render json: @promotion.errors, status: :unprocessable_entity }
end
end
end
help please :)
參考解法
方法 1:
It looks as though params[:user_id] did not contain a valid user id. Since you used find_by_id instead of find, it quietly assigned nil to @user, and of course nil doesn't have a method named #promotions, so that line failed.
You need to either check for @user being nil, or change User.find_by_id to User.find and then rescue ActiveRecord::RecordNotFound. In either case, respond with a custom 404 or whatever other way seems appropriate.
One other question, is it your intention that a user can create promotions for any other user? If they should only be creating promotions for themselves, you can avoid this whole mess by just eliminating the whole User.find_by_id line, and changing the next line to:
@promotion = current_user.promotions.create(params[:promotion])
Devise should have already current_user for you. In any case, you also need to handle what happens if the promotion cannot be created because there are validation errors in the user‑supplied parameters.
(by javierZanetti、sockmonk)