Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 Nested Models unknown attribute Error

  • I have a model "Issue" and a nested Model "Relationship"
  • In the issue.rb I have mentioned:

    has_many :relationships, :dependent => :destroy
    accepts_nested_attributes_for :relationships, :allow_destroy => true
    
  • In relationship.rb I have mentioned:

    belongs_to :issue
    
  • Following Ryan Bates Railcast#196 I have the following in my issues_controller:

    relationship = @issue.relationships.build
    

However, I am encountering an error "unknown attribute: relationship"

Am I doing something incorrectly here? I do see the Relationships Attributes being passed to the server in the log however, this error does not let the create to be successful.

My expertise with rails is beginners level so kindly excuse me if I am asking a question which maybe deemed trivial.

Thanks for the help.

EDIT: The relevant Controller code:

    @relationship = @issue.relationships.build
    #@relationship = Relationship.new(params[:relationship])
    if @relationship.issue_id = ''
      @relationship.issue_id = @issueid
    end

    if @relationship.cause_id = ''
      @relationship.cause_id = @issueid
    end

    @relationship.save
    redirect_to(:back, :notice => 'New Relationship was created') 

What I see on the trace:

    ActiveRecord::UnknownAttributeError in IssuesController#create
    unknown attribute: relationship

Among the Issue parameters, I see the Relationship params being passed as expected:

    "relationship"=>{"issue_id"=>"100",
    "cause_id"=>""}

ANOTHER UPDATE Posting the form_for code:

    - form_for Issue.new do |f|

      .field  
        = f.text_field :description, :class=>"formfield", :id=>"frm_descr"

      .field  
        = f.hidden_field :wiki_url, :class=>"formfield", :id=>"frm_wiki_url"

      .field
        = f.hidden_field :short_url, :class=>"formfield", :id=>"frm_img_url"

      .field
        = f.hidden_field :title, :class=>"formfield", :id=>"frm_title"         

      = f.fields_for :relationship do |builder|
        = builder.text_field :issue_id, :class=>"form_field", :id=>"frm_rel_issue_id", :value=>@issue.id 
        = builder.text_field :cause_id, :class=>"form_field", :id=>"frm_rel_cause_id"

      .actions
        = f.submit 'Create', :class=>"save_button", :name=>"save_issue_rel_button", :id=>"val_collector"
like image 920
rgoraya Avatar asked Jul 27 '11 00:07

rgoraya


2 Answers

Change this line

= f.fields_for :relationship do |builder|

to this:

= f.fields_for :relationships do |builder|

Your issue has_many relationships - plural. That will give you the correct relationships_attributes parameters.

like image 164
Thilo Avatar answered Sep 19 '22 23:09

Thilo


Here is the working skeleton code: I created a new project and tried the combination of the other answers, and finally made it to work.

Here is my solution, after that are the things to watch out for. I am using different models so bear with me:

  • My models are: discussion has_many posts.
  • Discussion has no attributes.
  • Posts has content:text and discussion_id:integer.

Working Code

(model) discussion.rb

has_many :posts
accepts_nested_attributes_for :posts

(model) post.rb

belongs_to :discussion

routes.rb

resources :discussions do
  resources :posts
end

(discussion view) _form.html.erb

<%= form_for(@discussion) do |f| %>
  <%= f.fields_for :posts, @post do |p| %>
    <%= p.text_area :content %>
  <% end %>
  <%= f.submit %>
<% end %>

(controller) discussions_controller.rb

  def new
    @discussion = Discussion.new
    @post = @discussion.posts.build

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @discussion }
    end
  end

  def create
    @discussion = Discussion.new(params[:discussion])

    respond_to do |format|
      if @discussion.save
        format.html { redirect_to(@discussion, :notice => 'Discussion was successfully created.') }
        format.xml  { render :xml => @discussion, :status => :created, :location => @discussion }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @discussion.errors, :status => :unprocessable_entity }
      end
    end
  end

Possible things that can go wrong

First, Thilo was right, I get unknown attribute: post if I do

# WRONG!
f.fields_for :post

Second, I have to have the @post instance variable in new action otherwise the post.context textarea will not show up.

# REQUIRED!
@post = @discussion.posts.build

Third, If I use the f.fields_for @post, the create action will complain unknown attribute: post too.

# WRONG!
f.fields_for @post do |p|

Use this instead:

# RIGHT!
f.fields_for :posts, @post  do |p|

The End

So yeah, I wish we get to see more documentations on this (can't see any useful ones). For example I see some use of form_for [@discussion, @post] but I can never get it to work.

like image 36
lulalala Avatar answered Sep 21 '22 23:09

lulalala