开发者

simple_form_for error: undefined method - associated models

In my rails application I have two associated models called Magazine and Article.

Magazine

class Magazine < ActiveRecord::Base
  has_many :articles
end

Article

class Article < ActiveRecord::Base
  belongs_to :magazine
end

Routes

Magazineapp::Application.routes.draw do
  resources :magazines do
    resources :articles
  end
end

schema.rb

create_table "articles", :force => true do |t|
  t.string   "title"
  t.string   "author"
  t.integer  "magazine_id"
  t.datetime "created_at"
  t.datetime "updated_at"
end

create_table "magazines", :force => true do |t|
  t.string   "title"
  t.datetime "created_at"
  t.datetime "updated_at"
end

I am trying to create a new article associated to a magazine from the article's new page. So, I created a link in the magazine's show page to pass the selected magazine to the new article's page.

views/magazines/show.html.erb

<p id="notice"><%= notice %></p>
<p>
  <b>Title:</b>
  <%= @magazine.title %>
</p>

<%= link_to 'Edit', edit_magazine_path(@magazine) %> |
<%= link_to 'Back', magazines_path %> |
<%= link_to 'New Article', new_magazine_article_path(@magazine) %>

The partial that is rendered in the article's new page is:

views/articles/_form.html.erb

<%= simple_form_for([@magazine, @article]) do |f| %>
  <%= f.error_notification %>

  <div class="inputs">
    <%= f.input :title %>
    <%= f.input :author %>
  </div>

  <div class="actions">
    <%= f.button :submit %>
  </div>
<% end %>

And the create method from the article's controller is:

def create

  @magazine = Magazine.find(params[:magazine_id])    
  @article = @magazine.articles.create(params[:article])

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

But when I try to create a new article associated to the magazine I get the error message:

Showing /home/wilson/magazineapp/app/views/articles/_form.html.erb where line #1 raised:

undefined method `articles_path' for #<#<Class:0x00000001944070>:0x00000001926ed0>
Extracted source (around line #1):

1: <%= simple_form_for([@magazine, @article]) do |f| %>
2:   <%= f.error_notification %>
3: 
4:   <div class="inputs">

Request

Parameters:

{"magazine_id"=>"2"}

rake routes

    magazine_articles GET    /magazines/:magazine_id/articles(.:format)          {:action=>"index", :controller=>"articles"}
                      POST   /magazines/:magazine_id/articles(.:format)          {:action=>"create", :controller=>"articles"}
 new_magazine_article GET    /magazines/:magazine_id/articles/new(.:format)      {:action=>"new", :controller=>"articles"}
edit_magazine_article GET    /magazines/:magazine_id/articles/:id/edit(.:format) {:action=>"edit", :controller=>"articles"}
     magazine_article GET    /magazines/:magazine_id/articles/:id(.:format)      {:action=>"show", :controller=>"articles"}
                      PUT    /magazines/:magazine_id/articles/:id(.:format)      {:action=>"update", :controller=>"articles"}
                      DELETE /magazines/:magazine_id/articles/:id(.:format)      {:action=>"destroy", :controller=>"articles"}
            magazines GET    /magazines(.:format)                                {:action=>"index", :controller=>"magazines"}
                      POST   /magazines(.:format)                                {:action=>"create", :controller=&g开发者_运维技巧t;"magazines"}
         new_magazine GET    /magazines/new(.:format)                            {:action=>"new", :controller=>"magazines"}
        edit_magazine GET    /magazines/:id/edit(.:format)                       {:action=>"edit", :controller=>"magazines"}
             magazine GET    /magazines/:id(.:format)                            {:action=>"show", :controller=>"magazines"}
                      PUT    /magazines/:id(.:format)                            {:action=>"update", :controller=>"magazines"}
                      DELETE /magazines/:id(.:format)                            {:action=>"destroy", :controller=>"magazines"}

How can I solve this problem? What are the correct parameters to pass to the simple_form_for in this case?


When you have nested resources you have to assure that you always pass the higher level resource between your requests.

Your routes will be the ones you have noticed using rake routes.

The form should be like this:

<%= simple_form_for([@magazine, @article]) do |f| %>
  <%= f.error_notification %>

  <div class="inputs">
    <%= f.input :title %>
    <%= f.input :author %>
  </div>    
  <div class="actions">
    <%= f.button :submit %>
  </div>
<% end %>

This way now you have to use the new routes everywhere on your articles controller and articles view pages, which will include the magazine itself.

Your create action in the controller would be:

def create

  @magazine = Magazine.find(params[:magazine_id])    
  @article = @magazine.articles.create(params[:article])

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

So now all your routes should reference @magazine too.


Run rake routes in your console and make sure that articles_path exists. Seems to be it should be named magazines_articles_path(...)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜