blippolis
blippolis

Reputation: 1

What is the difference between User.last and User.find_by_id(params[:user_id]) in create action?

I am getting the following error for my charges create action. Error: undefined method `shop' for nil:NilClass

This action is meant to create a new charge using stripe on a users "shop" page.

My model relations are as follows.

User has_one Shop, Shop belongs_to User, Shop has_many Charges, Charge belongs_to Shop

I have included the create action code from the charges controller below.

def create
    @user = User.find_by_id(params[:user_id])
    @shop = @user.shop
    @charge = @shop.charges.build(charge_params)

    if @charge.save
        redirect_to root_path
    else
        flash[:danger] = "Error"
        redirect_to root_path
    end
end

Why does that syntax for identifying the user not work when something like User.last.shop.charges.build(charge_params) does?

Interestingly enough, in the show action the line User.find_by_id(params[:user_id]) works fine.

Upvotes: 0

Views: 342

Answers (2)

Maxim Krizhanovsky
Maxim Krizhanovsky

Reputation: 26719

User.last returns the last record from the database. The only way it can fail is if there are no records at all.

The use_by_id version however tries to find specific record in the database, and it may fail if there is no record with this id. You have to handle such failures.

In such application you may want to deal with the current_user (currently logged in user), for which you can use the devise helper methods

Upvotes: 0

Omkar
Omkar

Reputation: 112

Use @user = User.find(params[:user_id]) or @user = User.find_by!(id: params[:user_id]) instead of @user = User.find_by_id(params[:user_id]). This will raise ActiveRecord::RecordNotFound Error and ultimately It will redirect to 404 page.

Finder methods like find_by_* are deprecated in Rails 4 and extracted to gem activerecord-deprecated_finders. Make sure you are using Rails 3 or lesser version.

Upvotes: 0

Related Questions