Reputation: 13378
In Rails, we define the create
action 2 ways. What are the difference?
def create
@shop = Shop.new(params[:shop])
if @shop.save
flash[:success] = 'Thanks for adding new shop.'
redirect_to @shop
else
flash[:error] = 'Error adding review, please try again.'
redirect_to @shop
end
end
# or
def create
@shop = Shop.create(params[:shop])
if @shop.save
flash[:success] = 'Thanks for adding new shop.'
redirect_to @shop
else
flash[:error] = 'Error adding review, please try again.'
redirect_to @shop
end
end
Considering we already have:
def new
@shop = Shop.new
end
Which is more proper?
Upvotes: 3
Views: 1221
Reputation: 230346
In create
controller action, Shop.new
is useless without following @shop.save
. Usually it's being split into these two steps to handle validation errors. We init shop with data from the user. If data is ok, we save the shop. If there are validation errors, we tell user to try again.
Or we need to do some complex attribute initialisation before we save record to the database.
@user = User.new params[:user]
@user.reputation = fetch_reputation_from_stackoverflow
if @user.save
# the usual steps here
Considering we already have:
def new
@shop = Shop.new
end
What is there in new
action is completely irrelevant. If your validations might fail (or otherwise your model might not be created successfully), then use new
+ save
pair. If you are sure that input data is ok and model will always save, then use only create
(following save
is redundant).
Upvotes: 1
Reputation: 23344
If you used Model.create
, you don't need to save the object explicitly. The create method will do that for you.
If you used Model.new
, you need to save the object by doing @object.save. The new
method does not do that for you.
Using Model.new:
def create
@shop = Shop.new(params[:shop])
if @shop.save
flash[:success] = 'Thanks for adding new shop.'
redirect_to @shop
else
flash[:error] = 'Error adding review, please try again.'
redirect_to @shop
end
end
Using Model.create:
def create
@shop = Shop.create(params[:shop])
# if @shop.save (This is not required)
if @shop
flash[:success] = 'Thanks for adding new shop.'
redirect_to @shop
else
flash[:error] = 'Error adding review, please try again.'
redirect_to @shop
end
end
Upvotes: 2
Reputation: 7725
The first way doesn't do what you expect:
def create
@shop = Shop.new(params[:shop]) # This won't create a new record on Shops table unless...
@show.save # ...you do this
end
def create
@shop = Shop.create(params[:shop]) # This will create a new record if everything is fine
if @shop.save # This is redundant
# ...
end
end
Calling create
and then save
is redundant. The create
method will try to make a new record and fail silently if validations are not successful. In the other hand, save
will try to make a new record, but returns nil
if vaildations fail, so you can use it in a if/else block.
Upvotes: 2
Reputation: 10874
This def new
action is just for the New
view (the new
action in your Shop
controller would correspond to the app/views/shop/new.html.erb
file) - it doesn't do any creation:
def new
@shop = Shop.new
end
There is no mention of params[:shop]
in that action, because the parameters don't exist yet - that's what you're gathering in the New
view.
Your def create
action is the action that actually creates the database entry:
def create
@shop = Shop.new(params[:shop])
if @shop.save
flash[:success] = 'Thanks for adding new shop.'
redirect_to @shop
else
flash[:error] = 'Error adding review, please try again.'
redirect_to @shop
end
end
You're using .new
instead of .create
so that you can do validations. Also, the Shop.new
call doesn't actually create the record - it's @shop.save
that does that.
Upvotes: 3