Question

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 :)

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top