3

I'm having a time trying to get this nested model working. I've tried all manner of pluralization/singular, removing the attr_accessible altogether, and who knows what else.

restaurant.rb:

# == RESTAURANT MODEL
#
# Table name: restaurants
#
#  id         :integer          not null, primary key
#  name       :string(255)
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Restaurant < ActiveRecord::Base
  attr_accessible :name, :job_attributes

  has_many    :jobs
  has_many    :users, :through => :jobs
  has_many    :positions

  accepts_nested_attributes_for :jobs, :allow_destroy => true

  validates :name, presence: true

end

job.rb:

# == JOB MODEL
#
# Table name: jobs
#
#  id            :integer          not null, primary key
#  restaurant_id :integer
#  shortname     :string(255)
#  user_id       :integer
#  created_at    :datetime         not null
#  updated_at    :datetime         not null
#

class Job < ActiveRecord::Base
  attr_accessible :restaurant_id, :shortname, :user_id

  belongs_to    :user
  belongs_to    :restaurant
  has_many      :shifts


  validates :name, presence: false

end

restaurants_controller.rb:

class RestaurantsController < ApplicationController

  before_filter :logged_in, only:  [:new_restaurant]

  def new
    @restaurant = Restaurant.new
    @user = current_user
  end

  def create
    @restaurant = Restaurant.new(params[:restaurant])
    if @restaurant.save
      flash[:success] = "Restaurant created."  
      redirect_to welcome_path
    end
  end

end

new.html.erb:

<% provide(:title, 'Restaurant') %>

  <%= form_for @restaurant do |f| %>
        <%= render 'shared/error_messages' %>

        <%= f.label "Restaurant Name" %>
        <%= f.text_field :name %>

        <%= f.fields_for :job do |child_f| %>

              <%= child_f.label "Nickname" %>
              <%= child_f.text_field :shortname %>

        <% end %>

        <%= f.submit "Done", class: "btn btn-large btn-primary" %>

  <% end %>

Output Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"DjYvwkJeUhO06ds7bqshHsctS1M/Dth08rLlP2yQ7O0=",
 "restaurant"=>{"name"=>"The Pink Door",
 "job"=>{"shortname"=>"PD"}},
 "commit"=>"Done"}

The error i'm receiving is:

ActiveModel::MassAssignmentSecurity::Error in RestaurantsController#create

Cant mass-assign protected attributes: job
Rails.root: /home/johnnyfive/Dropbox/Projects/sa

Application Trace | Framework Trace | Full Trace
app/controllers/restaurants_controller.rb:11:in `new'
app/controllers/restaurants_controller.rb:11:in `create'

Anyone have ANY clue how to get this to work? Thanks!

Baylor Rae'
  • 3,995
  • 20
  • 39
Morgan
  • 196
  • 9
  • 1
    Unrelated to your question - I noticed the comments at the top of each class defining the database structure. This is a pain to keep up to date, and can very easily get stale. Rails does a good job of keeping schema.rb up to date automatically when you run migrations, and may be a better way for you to document your database against your models. – Michael Shimmins Sep 12 '12 at 09:38
  • 1
    @MichaelShimmins I don't do it, it's done by the gem 'annotate'. – Morgan Sep 12 '12 at 16:49

2 Answers2

3

in restaurant.rb:

it should be attr_accessible :name, :jobs_attributes instead of attr_accessible :name, :job_attributes

Sergey Kishenin
  • 5,099
  • 3
  • 30
  • 50
infiniteloop
  • 371
  • 3
  • 7
  • Thanks for that (wasn't quite sure), however I have that in my current iteration and i'm still receiving the same error. – Morgan Sep 12 '12 at 03:29
  • 1
    Restaurant model has many jobs, so i guess you should put `<%= f.fields_for :jobs do |child_f| %>` instead of `:job` – Sergey Kishenin Sep 12 '12 at 03:38
  • @Kishie, I agree with you, and have tried that as well, however when I do, the 'shortname' field disappears altogether when viewed in a browser. I'm sure it's something stupid simple, but I can't figure it out for the life of me. – Morgan Sep 12 '12 at 03:43
  • @JohnnyFive everything @kishie has said is correct. I think your problem is a result of not having any job records added to your `@restraunt` object. What happens if you follow @kishie's advice _and_ add `3.times { @restaurant.jobs.build }` to the end of the `RestaurantsController#new` action. – Baylor Rae' Sep 12 '12 at 04:24
  • @BaylorRae' it worked! Thanks! Do you have any more of an explanation as to why this is? I have not seen any documentation on anything similar to this, so any information/docs/etc would be great! Again, thanks! – Morgan Sep 12 '12 at 05:21
  • 2
    @JohnnyFive it was because `f.fields_for` was trying to loop through all the jobs that were associated with the `@restaurant` object. But, because the `@restaurant` was a new object you needed to manually add some default jobs. For more information on how nested forms work take a look at the videos on http://railscasts.com/episodes/196-nested-model-form-part-1 That's where I learned how to use nested forms. – Baylor Rae' Sep 12 '12 at 05:30
  • @BaylorRae' Thanks for the help. This is above and beyond, but the last issue i'm having pertaining to this is that the user_id in the job model is not being filled out. I'm fairly certain the associations are in place, what else do I need to call to fill out that column as well? – Morgan Sep 12 '12 at 06:14
  • @JohnnyFive that almost needs to be its own question. You will probably need to add a dropdown within your `f.fields_for` block. `<%= child_f.collection_select :user_id, User.order(:name), :id, :name %>`. – Baylor Rae' Sep 12 '12 at 13:24
  • @JohnnyFive glad you got it working. If infiniteloop has answered your question you need to mark it as the accepted answer. – Baylor Rae' Sep 12 '12 at 17:13
  • @BaylorRae' Well his didn't.. yours did in this thread did.. so thanks to you. – Morgan Sep 12 '12 at 17:25
0

regarding your last comment: you can submit the user_id within your job form, that should submit the user_id to the model

Flo
  • 540
  • 6
  • 20