Reputation: 27
I have three models, Server has many maintenances and Maintenance belongs to Server and User.
create_table :maintenances do |t|
t.references :server, foreign_key: true
t.references :user, foreign_key: true
t.string :name
t.text :content
end
In console I can create records as follows:
Server.create(:hostname => "Sissy", :description => "Webserver")
Maintenance.create(:server_id => 1, :user_id => 1, :name => "Test", :content => "Test" )
My Question is: How can I do this in my Controller create action?
Problem is that :user_id
is not part of the maintenance params hash, so if I write
def create
@server = Server.find(params[:id])
@maintenance = @server.maintenances.create!(maintenance_params)
end
private
def maintenance_params
params.require(:maintenance).permit(:user_id => current_user.id,
:id,
:name,
:content)
end
I'm getting
Syntax error, unexpected ',', expecting =>
...ser_id => current_user.id, :id, :name, :content, :start, :pl...
... ^):
app/controllers/maintenances_controller.rb:41: syntax error, unexpected ',', expecting =>
Upvotes: 1
Views: 1343
Reputation: 101811
A good way is by passing a block to the create!
method:
@maintenance = @server.maintenances.create!(maintenance_params) do |m|
m.user = current_user
end
The record is yielded to the block (before it is validated/saved).
This also works with new
, create
, update
and update!
.
But you should consider if you should be using the bang method create!
here as it will raise an uncaught ActiveRecord::RecordNotValid
error if any of the validations fail.
def create
@server = Server.find(params[:id])
@maintenance = @server.maintenances.new(maintenance_params) do |m|
m.user = current_user
end
if @maintenance.save
redirect_to @maintenance
else
render :new
end
end
The ActiveRecord::Persistence bang methods should only really be used in things like seed files or where a record not passing the validations is an exceptional event.
Upvotes: 2
Reputation: 646
You can add , user_id inside your create action itself. Try this.
def create
@server = Server.find(params[:id])
params[:maintenance][:user_id] = current_user.id
@maintenance = @server.maintenances.create!(maintenance_params)
end
Upvotes: 3
Reputation: 230286
Yes, you can't do anything like that in strong_params method. Nor is it its purpose. Separate the whitelisting and default params.
I usually do it like this:
def create
@server = Server.find(params[:id])
@maintenance = @server.maintenances.create!(maintenance_params.merge(user_id: current_user.id))
end
private
def maintenance_params
params.require(:maintenance).permit(:id, :name, :content)
end
Upvotes: 0