Reputation: 638
I've been going at this for about 5 hours now and have tried just about everything. I'm a front-end dev with limited rails experience so I could just be 100% off base.
Here are my models:
class Apartment < ActiveRecord::Base
validates :name, :amenities, presence: true
has_many :apartment_amenities
has_many :amenities, through: :apartment_amenities
accepts_nested_attributes_for :amenities
end
class Amenity < ActiveRecord::Base
validates :name, presence: true
has_many :apartment_amenities
has_many :apartments, through: :apartment_amenities
end
class ApartmentAmenity < ActiveRecord::Base
belongs_to :apartment
belongs_to :amenity
end
schema:
create_table "amenities", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "apartment_amenities", force: :cascade do |t|
t.integer "apartment_id"
t.integer "amenity_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "apartment_amenities", ["amenity_id"], name: "index_apartment_amenities_on_amenity_id", using: :btree
add_index "apartment_amenities", ["apartment_id"], name: "index_apartment_amenities_on_apartment_id", using: :btree
create_table "apartments", force: :cascade do |t|
t.string "name"
t.string "address"
t.string "website"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Apartment controller:
class Admin::ApartmentsController < AdminController
before_action :set_apartment, only: [:edit, :update, :destroy]
def new
@apartment = Apartment.new
end
def create
@apartment = Apartment.new(apartment_params)
respond_to do |format|
if @apartment.save
format.html { redirect_to apartments_path, notice: 'Apartment was successfully created.' }
format.json { render :show, status: :created, location: @apartment }
else
format.html { render :new }
format.json { render json: @apartment.errors, status: :unprocessable_entity }
end
end
end
private
def set_apartment
@apartment = Apartment.find(params[:id])
end
def apartment_params
params.require(:apartment).permit(:name, :address, :website, amenities_attributes: [:id])
end
end
and last but not least the new apartment form
<%= form_for([:admin, @apartment]) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.collection_check_boxes(:amenities, Amenity.all, :id, :name ) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Everything looks right when I load the page up and the apartments are saved but the amenities aren't actually getting saved. Thanks for taking a look.
Upvotes: 1
Views: 334
Reputation: 356
I think you need to permit the name for amenities_attributes
as follows:
def apartment_params
params.require(:apartment).permit(:name, :address, :website, amenities_attributes: [:id, :name])
end
Upvotes: 0
Reputation: 2927
Its because your form fields don't match your strong params. Look at the source code of your form. I suspect you'll find that the n checkboxes look something like
apartment[amenities]
But your strong params has the amenities_attributes as a nested hash. Look at the params hash in the logs and you'll see how the form data is formatted. You'll need to change the form to use a fields_for or change the strong params
params.require(:apartment).permit(:name, :address, :website, amenities: [])
Upvotes: 2