Reputation: 2941
I'm working on a Rails 7 app. I have a form for creating companies
, each company can have multiple verticals
. I'm using form.collection_select
in the template to let users select one or many verticals. For some reason the create action tries to add the selected verticals twice. I've added a validation to not make that possible.
My relationships looks like this:
class Company < ApplicationRecord
has_many :company_verticals, dependent: :destroy
has_many :verticals, through: :company_verticals
class Vertical < ApplicationRecord
has_many :company_verticals
has_many :companies, through: :company_verticals
class CompanyVertical < ApplicationRecord
belongs_to :company
belongs_to :vertical
validates_uniqueness_of :vertical_id, scope: :company_id // causes rollback
The relevant parts of my companies controller looks like this:
# POST /companies or /companies.json
def create
@company = Company.new(company_params)
respond_to do |format|
if @company.save
# never reaches here since validation kicks in
def company_params
params.require(:company).permit(<...>, vertical_ids: [])
end
And my form looks like this
<%= form_with(model: @company, url: [@user, @company]) do |form| %>
...
<%= form.collection_select :vertical_ids, Vertical.all, :id, :name, { label: "Label" }, { multiple: true, class: input_classes } %>
When submitting the form I get the following output in the terminal:
↳ app/controllers/companies_controller.rb:30:in
block in create' CompanyVertical Exists? (0.5ms) SELECT 1 AS one FROM "company_verticals" WHERE "company_verticals"."vertical_id" = $1 AND "company_verticals"."company_id" = $2 LIMIT $3 [["vertical_id", 2], ["company_id", 16], ["LIMIT", 1]] ↳ app/controllers/companies_controller.rb:30:in
block in create' CompanyVertical Create (2.0ms) INSERT INTO "company_verticals" ("company_id", "vertical_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["company_id", 16], ["vertical_id", 2], ["created_at", "2022-11-27 20:16:57.465067"], ["updated_at", "2022-11-27 20:16:57.465067"]] ↳ app/controllers/companies_controller.rb:30:inblock in create' CompanyVertical Exists? (4.5ms) SELECT 1 AS one FROM "company_verticals" WHERE "company_verticals"."vertical_id" = $1 AND "company_verticals"."id" != $2 AND "company_verticals"."company_id" = $3 LIMIT $4 [["vertical_id", 2], ["id", 52], ["company_id", 16], ["LIMIT", 1]] ↳ app/controllers/companies_controller.rb:30:in
block in create' CompanyVertical Exists? (0.3ms) SELECT 1 AS one FROM "company_verticals" WHERE "company_verticals"."vertical_id" = $1 AND "company_verticals"."company_id" = $2 LIMIT $3 [["vertical_id", 2], ["company_id", 16], ["LIMIT", 1]] ↳ app/controllers/companies_controller.rb:30:in `block in create' TRANSACTION (0.7ms) ROLLBACK
If I remove the validation (validates_uniqueness_of :vertical_id, scope: :company_id
) it won't validate but the company will end up with duplicate verticals.
Any idea why this happens?
I'm using the same html template in my update method, but there it works fine.
Update
Params that gets passed to controller:
Parameters: {"authenticity_token"=>"[FILTERED]", "company"=>{"name"=>"Test", "registration_number"=>"12345", "vat_identification_number"=>"12345", "url_name"=>"test", "bio"=>"", "vertical_ids"=>["", "1", "2", "3"], "contact_information_attributes"=>{"email"=>"", "phone_number"=>""}, "user_id"=>"1", "address_attributes"=>{"country_id"=>"1", "street_address"=>"Test", "city"=>"test", "zip_code"=>"test"}}, "commit"=>"Skapa företag", "user_id"=>"1"}
Generated HTML:
<input name="company[vertical_ids][]" type="hidden" value="" autocomplete="off">
<select multiple="multiple" name="company[vertical_ids][]" id="company_vertical_ids">
<option selected="selected" value="1">Vert 1</option>
<option selected="selected" value="2">Vert 2</option>
<option selected="selected" value="3">Vert 3</option>
<option value="4">Vert 4</option>
</select>
Upvotes: 1
Views: 218