Nested has_many attributes (Ruby on Rails) throwing errors - ruby-on-rails
So this may be somewhat related to my question that I asked earlier, so here is a link to it, just in case.
So, currently I'm getting the error undefined method 'location' for #<Block:0x6503478>.
I've already gotten the has_one relation for cue working, but what seems to be the problem is the has_many relations with block_block and block_character.
The parameters being passed are:
{"utf8"=>"✓",
"authenticity_token"=>"blahblahblah",
"block"=>{"block_code"=>"1",
"block_duration"=>"",
"cue"=>"no",
"cue_attributes"=>{"cue_code"=>"",
"cue_type_code"=>"",
"cue_description"=>"",
"cue_method_code"=>""},
"location_code"=>"1",
"scene_code"=>"1",
"block_description"=>"",
"block_block"=>{"block_block_code"=>"",
"primary_block_code"=>"",
"secondary_block_code"=>"",
"block_block_start"=>""},
"block_character"=>{"block_character_code"=>"",
"character_code"=>"",
"block_code"=>"",
"character_action"=>"",
"character_motivation"=>""}},
"blockblock"=>{"block"=>"no"},
"blockblockdirect"=>{"blockdirect"=>"before"},
"blockchar"=>{"character"=>"no"},
"commit"=>"Create Block"}
Here is my form for block (views/block/_form.html.erb):
<%= form_for(#block) do |f| %>
<% if #block.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#block.errors.count, "error") %> prohibited this block from being saved:</h2>
<ul>
<% #block.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field hidden">
<%= f.label :block_code, class: "hidden" %><br>
<%= f.text_field :block_code, class: "form-control hidden" %>
</div>
<div class="field">
<%= f.label :block_duration %><br>
<div class="input-group">
<%= f.number_field :block_duration, class: 'text_field form-control', :step => 'any' %>
<div class="input-group-addon">seconds</div>
</div>
</div>
<div class="field">
<%= label "cue", "Does this block have a cue associated with it?" %>
<!-- Add whether it is specific/generic cue -->
<%= radio_button_tag "block[cue]", "yes", false %> Yes
<%= radio_button_tag "block[cue]", "no", true %> No
<div class="field" id="cue_fields" style="display:none;">
<%= f.fields_for :cue, #block.build_cue do |ff| %>
<div class="field hidden">
<%= ff.label :cue_code, class: "hidden" %><br>
<%= ff.text_field :cue_code, class: "hidden" %>
</div>
<div class="field">
<%= ff.label "Cue Type" %><br>
<%= ff.collection_select(:cue_type_code, CueType.all, :cue_type_code, :cue_type_name, {prompt: "Select a cue type..."}, {class: "form-control"}) %>
</div>
<div class="field">
<%= ff.label "Cue Description" %><br>
<%= ff.text_area :cue_description, class: "form-control" %>
</div>
<div class="field">
<%= ff.label "Cue Method" %><br>
<%= ff.collection_select( :cue_method_code, CueMethod.all, :cue_method_code, :cue_method_name, {prompt: "Select a cue method..."}, {class: "form-control"}) %>
</div>
<% end %>
</div>
</div>
<div class="field">
<%= f.label "Location" %><br>
<%= collection_select :block, :location_code, Location.all, :location_code, :location_name, {prompt: "Select a location..."}, {class: "form-control", required: true} %>
</div>
<div class="field">
<%= f.label "Scene" %><br>
<%= f.collection_select :scene_code, Scene.all, :scene_code, :actAndScene, {prompt: "Select a scene..."}, {class: "form-control", required: true} %>
</div>
<div class="field">
<%= f.label "Block Description" %><br>
<%= f.text_area :block_description, class: "form-control" %>
</div>
<!-- This needs work -->
<div class="field">
<%= label "blockblock", "Is this block associated with any other blocks?" %>
<%= radio_button_tag "blockblock[block]", "yes", false %> Yes
<%= radio_button_tag "blockblock[block]", "no", true %> No
<div class="field" id="blockblock_fields" style="display:none;">
<ol>
<li>
<%= label "blockdirect", "Does this block come directly before or after another block?" %>
<%= radio_button_tag "blockblockdirect[blockdirect]", "before", true %> Before
<%= radio_button_tag "blockblockdirect[blockdirect]", "after", false %> After
<%= f.fields_for :block_block do |gg| %>
<div class="field hidden">
<%= gg.label :block_block_code, class: 'hidden' %><br>
<%= gg.text_field :block_block_code, class: 'hidden' %>
</div>
<div class="field" id="blockblock_after_fields" style="display:none;">
<%= gg.label "Primary Block Code" %><br>
<%= gg.text_field :primary_block_code, class: 'form-control' %>
</div>
<div class="field" id="blockblock_before_fields">
<%= gg.label "Secondary Block Code" %><br>
<%= gg.text_field :secondary_block_code, class: 'form-control' %>
</div>
<div class="field">
<%= gg.label "Block Start" %><br>
<p><i>This field indicates the amount of time after the first block starts that the second block should begin, i.e. if you type "1" here, then the second block will start 1 second after the first block starts</i></p>
<div class="input-group">
<%= gg.number_field :block_block_start, class: 'text_field form-control', :step => 'any' %>
<div class="input-group-addon">seconds</div>
</div>
</div>
<% end %>
</li>
</ol>
</div>
</div>
<!-- This needs work -->
<div class="field">
<%= label "character", "Are any characters associated with this block?" %>
<%= radio_button_tag "blockchar[character]", "yes", false %> Yes
<%= radio_button_tag "blockchar[character]", "no", true %> No
<div class="field" id="character_fields" style="display:none;">
<ol>
<%= f.fields_for :block_character do |hh| %>
<li>
<div class="field hidden">
<%= hh.label :block_character_code, class: 'hidden' %><br>
<%= hh.text_field :block_character_code, class: 'hidden' %>
</div>
<div class="field">
<%= hh.label "Character" %><br>
<%= hh.collection_select :character_code, Character.all, :character_code, :character_name, {prompt: "Select a character..."}, {class: "form-control"} %>
</div>
<div class="field hidden">
<%= hh.label :block_code, class: 'hidden' %><br>
<%= hh.text_field :block_code, class: 'hidden' %>
</div>
<div class="field">
<%= hh.label :character_action %><br>
<%= hh.text_field :character_action, class: 'form-control' %>
</div>
<div class="field">
<%= hh.label :character_motivation %><br>
<%= hh.text_area :character_motivation, class: 'form-control' %>
</div>
</li>
<% end %>
</ol>
</div>
</div>
<div class="actions">
<%= f.submit "Create Block", class: "btn btn-primary" %>
</div>
<% end %>
Additionally, here are the models associated with block, block_character, and block_block, respectively:
class Block < ActiveRecord::Base
validates_presence_of :location
validates_presence_of :scene
has_one :cue
has_many :block_blocks
has_many :block_characters
accepts_nested_attributes_for :cue, allow_destroy: true
accepts_nested_attributes_for :block_blocks, allow_destroy: true
accepts_nested_attributes_for :block_characters, allow_destroy: true
attr_accessor :block_blocks
attr_accessor :block_characters
end
class BlockBlock < ActiveRecord::Base
belongs_to :block
end
class BlockCharacter < ActiveRecord::Base
belongs_to :block
end
Here is the controller for block:
class BlocksController < ApplicationController
before_action :set_block, only: [:show, :edit, :update, :destroy]
# GET /blocks
# GET /blocks.json
def index
#blocks = Block.all
end
# GET /blocks/1
# GET /blocks/1.json
def show
end
# GET /blocks/new
def new
#block = Block.new
# Set block code as next integer after max block code.
#block.block_code = (Block.maximum(:block_code).to_i.next).to_s(2)
end
# GET /blocks/1/edit
def edit
end
# POST /blocks
# POST /blocks.json
def create
#block = Block.new(block_params)
respond_to do |format|
if #block.save
format.html { redirect_to #block, notice: 'Block was successfully created.' }
format.json { render :show, status: :created, location: #block }
else
format.html { render :new }
format.json { render json: #block.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /blocks/1
# PATCH/PUT /blocks/1.json
def update
respond_to do |format|
if #block.update(block_params)
format.html { redirect_to #block, notice: 'Block was successfully updated.' }
format.json { render :show, status: :ok, location: #block }
else
format.html { render :edit }
format.json { render json: #block.errors, status: :unprocessable_entity }
end
end
end
# DELETE /blocks/1
# DELETE /blocks/1.json
def destroy
#block.destroy
respond_to do |format|
format.html { redirect_to blocks_url, notice: 'Block was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_block
#block = Block.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def block_params
params.require(:block).permit(:block_code, :block_duration, :cue_code, :location_code, :scene_code, :block_description, :cue_attributes => [:id, :cue_code, :cue_type_code, :cue_description, :cue_method_code], :block_block_attributes => [:id, :block_block_code, :primary_block_code, :secondary_block_code, :block_block_start], :block_character_attributes => [:id, :block_character_code, :character_code, :block_code, :character_action, :character_motivation])
end
end
And finally, the migrations I added for id and foreign_key for both block_block and block_character:
class AddBelongsToToBlockBlocks < ActiveRecord::Migration
def change
add_reference :block_blocks, :block, index: true
add_foreign_key :block_blocks, :blocks
end
end
class AddBelongsToToBlockCharacters < ActiveRecord::Migration
def change
add_reference :block_characters, :block, index: true
add_foreign_key :block_characters, :blocks
end
end
Honestly, thank you all so much for your help through this, I am by no means an advanced Rails user and this has all been amazingly helpful. Please let me know if you need any more information!
UPDATE 1
So I changed the following in block.rb (the model file), as suggested by Vijay (thanks so much!!!):
class Block < ActiveRecord::Base
validates_presence_of :location_code
validates_presence_of :scene_code
has_one :cue
has_many :block_blocks
has_many :block_characters
accepts_nested_attributes_for :cue, allow_destroy: true
accepts_nested_attributes_for :block_blocks, allow_destroy: true
accepts_nested_attributes_for :block_characters, allow_destroy: true
attr_accessor :block_blocks
attr_accessor :block_characters
end
At this point, the block saves (and appears in the index view), but the block_block and block_character do not do so. There is no associated error however...
UPDATE 2
This is currently what the params submitted look like:
Which is odd because it says that cue, block_block, and block_character are unpermitted parameters, even though, in the controller they are:
def block_params
params.require(:block).permit(:block_code, :block_duration, :cue_code, :location_code, :scene_code, :block_description, :cue_attributes => [:id, :cue_code, :cue_type_code, :cue_description, :cue_method_code], :block_block_attributes => [:id, :block_block_code, :primary_block_code, :secondary_block_code, :block_block_start], :block_character_attributes => [:id, :block_character_code, :character_code, :block_code, :character_action, :character_motivation])
end
Are you triggering the error in the validation?
validates_presence_of :location
From your code it looks like it should be
validates_presence_of :location_code
Not sure why you've added these in Rails 4
attr_accessor :block_blocks
attr_accessor :block_characters
Try removing them and see if they are interfering with the controller (I'm guessing, but happy to play if you put up a jsfiddle)
Related
Using validations and pluralize in views to show errors count for forms rails 7
i am trying to display a message for whenever someone does not fill the form completely and press the submit button! Example: when someone clicks the submit button without filling the Name and Email field in the form, it should display 2 Errors Prohibited from submitting the form! . Name can't be blank . Email can't be blank but it is not being displayed whenever we submit the form with empty fields can someone explain me the reason why it is not working? Orders_controller.rb class OrdersController < ApplicationController # GET to /orders/new def new #order = Order.new end # POST to /orders def create #order = Order.new(order_params) respond_to do |format| if #order.save! format.html{ redirect_to root_url, notice: "Order Succesfully Submitted!" } else format.html{ render :new, status: :unprocessable_entity } end end end private def order_params params.require(:order).permit(:first_name, :last_name, :phone_number, :email, :paper_size, :color, :paper_style, :quantity, :description, files: [] ) end end _form.html.erb (i already rendered the partial in new.html.erb by <%= render 'form', order: #order%> <div class="container"> <h1 class="text-center">Order From Home!</h1> <div class="row"> <div class="col-md-4 col-md-offset-4"> <%= form_with(model: order) do |f| %> <% if order.errors.any? %> <div style="color: red"> <h3><%= pluralize(order.errors.count,"errors")%> Prohibited from submitting the form! <br/> All Fields Are Required!</h3> <ul> <% order.errors.each do |error| %> <li><%= error.full_message %></li> <% end %> </ul> </div> <% end %> <%= f.label :first_name%> <%= f.text_field :first_name, class:"form-control" %><br/> <%= f.label :last_name %> <%= f.text_field :last_name, class:"form-control" %><br/> <%= f.label :phone_number %> <%= f.text_field :phone_number, class:"form-control" %><br/> <%= f.label :email %> <%= f.text_field :email, class:"form-control" %><br/> <%= f.label :files %> <%= f.file_field :files, multiple: true %><br/> <%= f.label :paper_size %> <%= f.select :paper_size, ['A4', 'B4'], { prompt: 'Select' }, class:'form-select' %><br/> <%= f.label :color %> <%= f.select :color, ['Black & White', 'Color'], { prompt: 'Select' }, class:'form-select' %><br/> <%= f.label :paper_style %> <%= f.select :paper_style, ['Black to Back', 'Side to Side'], { prompt: 'Select' }, class:'form-select' %><br/> <%= f.label :quantity %> <%= f.number_field :quantity, class:'form-control' %><br/> <%= f.label :description %> <%= f.text_area :description, class:"form-control" %><br/> <div class="btn-order"> <%= f.submit %> </div> <% end %> </div> </div> </div>
#order.save! raises validation errors. You don't need bang method if you want to render such errors, just use #order.save instead form_with sends XHR request. If you need to render something, you can disable Turbo for this form <%= form_with(model: order, data: { turbo: false }) do |f| %>
unknown attribute 'development_id' for Lot with cocoon triple nested forms
I'm almost certain I know what the problem is, and if I'm correct, I just can't find where the problem is lying. When triple-nesting with the cocoon gem, I'm having what seems to be an error with incorrect pluralisation. I have 3 resources, Developments > Lots > Listings, where Developments is the grandparent, Lots is the parent and Listings is the child. The error I'm getting is unknown attribute 'development_id' for Lot. stemming from ActiveModel::UnknownAttributeError in Developments#new. I've checked my models and partials and have been playing around with them. Here is my code: developments_controller.rb class DevelopmentsController < ApplicationController before_action :set_development, only: %i[ show edit update destroy ] # GET /developments or /developments.json def index #developments = Development.all end # GET /developments/1 or /developments/1.json def show end # GET /developments/new def new #development = Development.new end # GET /developments/1/edit def edit end # POST /developments or /developments.json def create #development = Development.new(development_params) respond_to do |format| if #development.save format.html { redirect_to #development, notice: "Development was successfully created." } format.json { render :show, status: :created, location: #development } else format.html { render :new, status: :unprocessable_entity } format.json { render json: #development.errors, status: :unprocessable_entity } end end end # PATCH/PUT /developments/1 or /developments/1.json def update respond_to do |format| if #development.update(development_params) format.html { redirect_to #development, notice: "Development was successfully updated." } format.json { render :show, status: :ok, location: #development } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: #development.errors, status: :unprocessable_entity } end end end # DELETE /developments/1 or /developments/1.json def destroy #development.destroy respond_to do |format| format.html { redirect_to developments_url, notice: "Development was successfully destroyed." } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_development #development = Development.find(params[:id]) end # Only allow a list of trusted parameters through. def development_params params.require(:development).permit(:development_name, :development_type, :development_address, :description, :estimated_completion_date, :body_corp, lots_attributes: [:id, :status, :stage, :land_size, :price, :eta, :_destroy, listings_attributes: [:id, :lot_number, :price, :type, :bed, :bath, :car, :house_size, :rent, :_destroy]]) end end development.rb (model) class Development < ApplicationRecord has_many :lots accepts_nested_attributes_for :lots, reject_if: :all_blank, allow_destroy: :true end Lot.rb (model) class Lot < ApplicationRecord has_many :listings accepts_nested_attributes_for :listings, reject_if: :all_blank, allow_destroy: :true belongs_to :development end Listing.rb (model) class Listing < ApplicationRecord belongs_to :lot end _form.html.erb (partial) <%= form_for #development do |f| %> <div class="field"> <%= f.label :development_name%> <%= f.text_field :development_name%> </div> <div class="field"> <%= f.label :development_type %> <%= f.text_field :development_type %> </div> <div class="field"> <%= f.label :development_address %> <%= f.text_field :development_address %> </div> <div class="field"> <%= f.label :description %> <%= f.text_area :description %> </div> <div class="field"> <%= f.label :estimated_completion_date %> <%= f.date_select :estimated_completion_date %> </div> <div class="field"> <%= f.label :body_corp %> <%= f.number_field :body_corp %> </div> <div id="listings"> <%= f.fields_for :lots do |lot| %> <%= render 'lot_fields', f: lot %> <% end %> <div class="links"> <%= link_to_add_association 'add lot', f, :lots %> </div> </div> <%= f.submit %> <% end %> _lot_fields.html.erb (partial) <div class="nested-fields"> <h3> New Lots </h3> <div class="field"> <%= f.label :status %> <br/> <%= f.text_field :status %> </div> <div class="field"> <%= f.label :stage %> <br/> <%= f.text_field :stage %> </div> <div class="field"> <%= f.label :land_size %> <br/> <%= f.text_field :land_size %> </div> <div class="field"> <%= f.label :price %> <br/> <%= f.text_field :price %> </div> <div class="field"> <%= f.label :eta %> <br/> <%= f.text_field :eta %> </div> <%= link_to_remove_association "remove lot", f %> </div> _listing_fields.html.erb (partial) <div class="nested-fields"> <h3> New Listing </h3> <div class="field"> <%= f.label :status %> <br/> <%= f.text_field :status %> </div> <div class="field"> <%= f.label :stage %> <br/> <%= f.text_field :stage %> </div> <div class="field"> <%= f.label :land_size %> <br/> <%= f.text_field :land_size %> </div> <div class="field"> <%= f.label :price %> <br/> <%= f.text_field :price %> </div> <div class="field"> <%= f.label :eta %> <br/> <%= f.text_field :eta %> </div> <%= link_to_remove_association "remove listing", f %> </div> new.html.erb <h1>New Development</h1> <%= render 'form', development: #development %> <%= link_to 'Back', developments_path %> I have a clone project of this and I noticed in the schema.rb that there is a key difference: t.index ["developments_id"], name: "index_lots_on_developments_id" I believe it should be development_id instead of being pluralised, but I'm not sure where/how this needs to be changed. I'm under the impression you should never alter a schema file. Any help is greatly appreciated!
Exactly, it should be : t.index ["development_id"], name: "index_lots_on_development_id" You have to rewrite a migration with def change remove_index :lots, name: "index_lots_on_developments_id" add_reference :lots, :development, index: true end
Type error on nested form
been banging my head on the table over this one. I have another nested form but this one is driving me crazy. The error is: TypeError in CompaniesController#create no implicit conversion of Symbol into Integer #company = Company.new(company_params) The controller: class CompaniesController < ApplicationController layout 'welcome' def new #company = Company.new end def create #company = Company.new(company_params) if #company.save flash[:notice] = "New company created successful." redirect_to admin_accounts_path else flash.now[:alert] = "Creation failed, please try again" render :new end end private def company_params params.require(:company).permit(:name, :location, :users_attributes => [:email, :password]) end end On the new.html.erb: <%= render partial: 'form', locals: { company: #company, users_attributes: :users_attributes } %> This code looks exactly like another nested setup I have, but it works :p I had read that sometimes changing the params from => to just having a semicolon works, but replacing the user_attributes => with a user_attributes: didn't change anything. EDIT: form.html.erb <%= form_for company, url: companies_path do |f| %> <div class="col-12"> <div class="row"> <div class="col p-0 mr-3"> <div class="form-group"> Company <%= f.label :name %> <%= f.text_field :name, :placeholder => 'Company name', class: 'form-control' %> </div> <div class="form-group"> <%= f.label :location %> <%= f.text_field :location, :placeholder => 'Location', class: 'form-control' %> </div> </div> <div class="col p-0"> <%= f.fields_for users_attributes do |user_f| %> <div class="form-group"> <%= user_f.label :email %> <%= user_f.text_field :email, :placeholder => 'Your Email Address', class: 'form-control' %> </div> <div class="form-group"> <%= user_f.label :password %> <%= user_f.password_field :password, :placeholder => 'Password', class: 'form-control' %> </div> <% end %> </div> <div class="col-12 p-0"> <%= f.submit "Sign-Up", :class => 'btn btn-primary btn-block btn-lg' %> </div> </div> </div> <% end %>
Use users instead of users_attributes on the form. Don't forget to define accepts_nested_attributes_for :users in model Company ## new.html.erb <%= render partial: 'form', locals: { company: #company, users_attributes: :users } %> I wonder why you didn't put :users into the form directly
Undefined method when saving an instance of my "Stop" model
My Rails App consists of touristic Routes. Each route has many stops and waypoints and stops have categories. Waypoints are just the intermediate model between routes and stops because stops can belong to many routes. So, when i try to save a Stop, i get the error: undefined method `category' for #<Stop:0x007fa067acea90> And the " if #stop.save" line is highlighted in red: respond_to do |format| if #stop.save Waypoint.create(route_id: params[:route_id] , stop_id: #stop.id) #print out category id or name here category = params[:category] In my stops controller i have this on create: def create #stop = Stop.new(stop_params) respond_to do |format| if #stop.save Waypoint.create(route_id: params[:route_id] , stop_id: #stop.id) #print out category id or name here category = params[:category] #once printed save it (stop category) StopCategory.create(category_id: category, stop_id: #stop.id) format.html { redirect_to #stop, notice: 'Stop was successfully created.' } format.json { render :show, status: :created, location:#stop } else format.html { render :new } format.json { render json: #stop.errors, status: :unprocessable_entity } end end And on my waypoints controller i have this on create: def create #waypoint = Waypoint.create(waypoint_params) redirect_to #waypoint.route end This is the stop model: class Stop < ActiveRecord::Base validates :description, length: { maximum: 140 } validates :category, presence: true #Image Uploader mount_uploader :stop_image, StopImageUploader #Relationship with stops and waypoints has_many :waypoints has_many :routes, through: :waypoints # Relationship with categories has_many :stop_categories has_many :categories, through: :stop_categories end And this is the view where the form is : <h2>Create a new stop:</h2><br> <%= form_for(#stop) do |f| %> <% if #stop.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(#stop.errors.count, "error") %> prohibited this stop from being saved:</h2> <ul> <% #stop.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :name %><br> <%= f.text_field :name %> </div> <select name="category" id=" " > <option value="" disabled selected> Select a Category </option> <% #categories.each do |category| %> <option value="<%= category.id %>"> <%= category.name %> </option> <% end %> </select> <div class="field"> <%= f.label :description %><br> <%= f.text_area :description %> </div> <div class="field"> <%= f.label :stop_image %><br> <%= f.file_field :stop_image %> </div> <div class="field"> <%= f.label :stop_lat %><br> <%= f.number_field :stop_lat, :class => 'text_field', :step => 'any' %> </div> <div class="field"> <%= f.label :stop_long %><br> <%= f.number_field :stop_long, :class => 'text_field', :step => 'any' %> </div> <%= hidden_field_tag :route_id, params[:id] %> <div class="actions"> <%= f.submit %> </div> <% end %> <h2>Add existing stop</h2> <br> <%= form_for(#waypoint) do |f| %> <div class="field"> <%= f.label :stop_id %><br> <%= f.number_field :stop_id %> </div> <%= f.hidden_field :route_id %> <div class="actions"> <%= f.submit %> </div> <% end %> <%= link_to 'Edit', edit_route_path(#route) %> | <%= link_to 'Back', routes_path %> <br> <br> <br> </div> Any ideas ? Thanks!
Do you have a 'category' attribute in your Stop model? If not, then the following doesn't make sense: validates :category, presence: true That is where it's probably failing. If you want to validate the presence of categories, you need to replace that check with something like this: validate :has_categories def has_categories # make this private if categories.blank? # add errors here end end The following might also work: validates :categories, presence: true
In the Stop model, you should replace the line validates :category, presence: true with validates :categories, presence: true because the validator takes the attribute/association name as argument, not the model name of the association. Your association is called categories, so that's what you need to perform the validation on.
Rails 4 oracle enhanced adapter many to many propagating data to the pivot table
First things first Using: rails4 oracle enhanced adapter rails4 branch I have a many to many relationship mapped on an existing database. My models look as such: class EventMap < ActiveRecord::Base self.table_name="TAKE_PART" self.primary_key="id" belongs_to :event, foreign_key: "lottery_event_id" belongs_to :entrant, foreign_key: "address_id" end class Event < ActiveRecord::Base self.table_name="THE_EVENT" self.primary_key="id" has_many :event_maps, :foreign_key => "lottery_event_id" has_many :entrants, :through => :event_maps accepts_nested_attributes_for :entrants, :reject_if => :all_blank end class Entrant < ActiveRecord::Base self.table_name="ADDRESSES" self.primary_key="id" self.set_date_columns :date_of_birth has_many :events, :through => :event_maps has_many :event_maps, :foreign_key => "address_id" end static page controller for my voting page ... def vote #event=Event.find_by(id: 4227) #entrants=#event.entrants #entrant=#event.entrants.build end ... vote view: <%= form_for(#event) do |f| %> <%= f.fields_for :entrant do |builder| %> <%= render "/entrants/fields", :f => builder %> <% end %> <div class="actions"> <%= f.submit %> </div> <% end %> entrant/fields partial: <% if #entrant.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(#entrant.errors.count, "error") %> prohibited this entrant from being saved:</h2> <ul> <% #entrant.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <%= f.hidden_field :id %> <div class="field"> <%= f.label :lastname %><br> <%= f.text_field :lastname %> </div> <div class="field"> <%= f.label :firstname %><br> <%= f.text_field :firstname %> </div> <div class="field"> <%= f.label :street %><br> <%= f.text_field :street %> </div> <div class="field"> <%= f.label :country_id %><br> <%= f.number_field :country_id %> </div> <div class="field"> <%= f.label :city %><br> <%= f.text_field :city %> </div> <div class="field"> <%= f.label :telephone %><br> <%= f.text_field :telephone %> </div> <div class="field"> <%= f.label :email %><br> <%= f.text_field :email %> </div> <div class="field"> <%= f.label :date_of_birth %><br> <%= f.date_select :date_of_birth %> </div> <div class="field"> <%= f.label :lang_id %><br> <%= f.text_field :lang_id %> </div> <div class="field"> <%= f.label :added %><br> <%= f.date_select :added %> </div> <div class="field"> <%= f.label :salut %><br> <%= f.text_field :salut %> </div> <div class="field"> <%= f.label :zip %><br> <%= f.text_field :zip %> </div> <div class="field"> <%= f.label :newsletter %><br> <%= f.check_box :newsletter %> </div> <div class="field"> <%= f.label :company %><br> <%= f.text_field :company %> </div> The form now submits to event controller PATCH class EventsController < ApplicationController before_action :set_event, only: [:show, :edit, :update, :destroy] ... # PATCH/PUT /events/1 # --> HOW DO I SAVE THE SUBMITTED ENTRANT HERE??? <-- def update respond_to do |format| if #event.update(event_params) format.html { redirect_to #event, notice: 'Event was successfully updated.' } format.json { head :no_content } else format.html { render action: 'edit' } format.json { render json: #event.errors, status: :unprocessable_entity } end end end ... private # Use callbacks to share common setup or constraints between actions. def set_event #event = Event.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def event_params params.require(:event).permit(:id, :lottery_id, :events_dates_id, :event_date, :event_location, :tickets_for_winner, :prize, :tickets_internally, :entrants_attributes => [:id, :lastname, :firstname, :street, :country_id, :city, :telephone, :email, :date_of_birth, :lang_id, :added, :salut, :zip, :newsletter, :company]) end end How do I register an Entrant with an Event, adding data only to the intermediate model EventMap since the Event will always exist? Do I need to include accepts_nested_attributes_for in my models to propagate changes accross tables (I could not quite figure out what this does from the documentation)? Do I need to send additional params via the Entrant form to update the EventMap? Main GOAL: I want a form where Entrants can register to an existing event!
Hard to judge about Your forms, as we don't see any ;) But You are right to be able to create nested attributes, from nested attributes from, You need to set accepts_nested_attributes_for :some_model, :some_other_model If You find docs confusing, consult Railscasts: http://railscasts.com/episodes/196-nested-model-form-part-1 http://railscasts.com/episodes/197-nested-model-form-part-2
You are requiring custom logic and that custom logic must be defined, Rails will not automatically update everything, it must be defined in the update controller as you suggest. I might do something along the lines of this: def update entrant = Entrant.find(params[:entrant_id]) event = Event.find(params[:event_id]) EventMap.create!(event: event, entrant: entrant) #.... go on with usual stuff # Alternatively you could use build event_map = EventMap.new event_map.build(event: event, entrant: entrant) end