Reputation: 369
I created a form where a user can create a profile. In the form the user can select multiple companies. A profile has many companies through a join-table named profile_companies. My code does create a new profile, but it does not create the association. Meaning that when I hit in the console: Profile.last.companies it returns an empty array. When I check the params before a profile is created, it does show me a full array for company_ids. So it looks like it cannot pass these values and create the association. Does anyone have an idea where the error is?
Here is my Profile model:
class Profile < ApplicationRecord
belongs_to :user
has_many :profile_companies
has_many :companies, through: :profile_companies
STATUSES = ["currently looking for a job", "employed but open for a new challenge"]
validates :status, inclusion: {in: STATUSES}
end
here is my company model:
class Company < ApplicationRecord
has_many :vacancies
has_many :profile_companies
has_many :profiles, through: :profile_companies
end
here is my profiles controller:
class ProfilesController < ApplicationController
def new
@profile = Profile.new
end
def create
@profile = Profile.new(params_profile)
if @profile.save
redirect_to profile_path
else
render :new
end
end
private
def params_profile
params.require(:profile).permit(:status, :name, :content, :company_ids)
end
end
And here is my pry to show the params handed to the controller:
[1] pry(#<ProfilesController>)> params[:profile] => <ActionController::Parameters {"name"=>"test 4", "status"=>"employed but open for a new challenge", "company_ids"=>["", "31", "34"], "content"=>"test 4"} permitted: false>
And here are my Logs:
Started POST "/profiles" for ::1 at 2019-08-05 22:54:36 +0200
Processing by ProfilesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"bmmqCdtWvTcDjlbR6yGrdZTGj+t3O2NMwNKanY5qP84eCSsCuBVF4SdzDkQ+0YOe5q+CapWx5NLaftunZ+ANSg==", "profile"=>{"name"=>"test 4", "status"=>"employed but open for a new challenge", "company_ids"=>["", "17", "31", "32"], "content"=>"rrr"}, "commit"=>"Save your profile"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 16], ["LIMIT", 1]]
Unpermitted parameter: :company_ids
(0.1ms) BEGIN
(0.1ms) ROLLBACK
Rendering profiles/new.html.erb within layouts/application
Company Load (2.6ms) SELECT "companies".* FROM "companies"
CACHE Company Load (0.0ms) SELECT "companies".* FROM "companies"
CACHE Company Load (0.0ms) SELECT "companies".* FROM "companies"
Rendered profiles/new.html.erb within layouts/application (29.2ms)
Rendered shared/_navbar.html.erb (1.4ms)
Rendered shared/_flashes.html.erb (0.4ms)
Completed 200 OK in 178ms (Views: 170.6ms | ActiveRecord: 3.2ms)
Upvotes: 0
Views: 319
Reputation: 20263
A couple of things. First, as you can see from the Unpermitted parameter: :company_ids
message:
Started POST "/profiles" for ::1 at 2019-08-05 22:54:36 +0200
Processing by ProfilesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"bmmqCdtWvTcDjlbR6yGrdZTGj+t3O2NMwNKanY5qP84eCSsCuBVF4SdzDkQ+0YOe5q+CapWx5NLaftunZ+ANSg==", "profile"=>{"name"=>"test 4", "status"=>"employed but open for a new challenge", "company_ids"=>["", "17", "31", "32"], "content"=>"rrr"}, "commit"=>"Save your profile"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 16], ["LIMIT", 1]]
Unpermitted parameter: :company_ids
(0.1ms) BEGIN
(0.1ms) ROLLBACK
Rendering profiles/new.html.erb within layouts/application
Company Load (2.6ms) SELECT "companies".* FROM "companies"
CACHE Company Load (0.0ms) SELECT "companies".* FROM "companies"
CACHE Company Load (0.0ms) SELECT "companies".* FROM "companies"
Rendered profiles/new.html.erb within layouts/application (29.2ms)
Rendered shared/_navbar.html.erb (1.4ms)
Rendered shared/_flashes.html.erb (0.4ms)
Completed 200 OK in 178ms (Views: 170.6ms | ActiveRecord: 3.2ms)
...you are using permit
incorrectly and company_ids
, therefore, is not being permitted.
It should look something more like:
def params_profile
params.require(:profile).permit(:status, :name, :content, company_ids: [])
end
...since company_ids
is an array. Permitted arrays should go at the end of the permit
list, see the docs for more information.
Second, your Profile
model doesn't have a company_ids
attribute. So, you may get an error when you do:
@profile = Profile.new(params_profile)
(TBH, I forget how smart (or not) rails is in this type of circumstance.) Which is a whole other thing you'll have to deal with.
Third, your Profile
model includes belongs_to :user
, but you never assign a user which is why your transaction is getting the ROLLBACK
. In general, to see why you're getting a ROLLBACK
, you can do something like:
if @profile.save!
...and the bang (!) will cause an error and provide an explanation.
To set the user_id
, I would suggest you do something like:
@profile = current_user.build_profile(params_profile)
This assumes that User
has_one :profile
. See the docs for more information.
Upvotes: 1