嵌套路由 - 破碎表单,NoMethodError - 未定义方法

时间:2015-05-26 04:27:56

标签: ruby-on-rails ruby associations nested-routes

要学习Rails,我正在开发一个简单的日历应用程序。首先,我创建了两个支架和正确的关联/路线:

  • 日历
  • content_items

应用/模型/ calendar.rb

class Calendar < ActiveRecord::Base
   has_many :content_items
end

应用/模型/ content_item.rb

class ContentItem < ActiveRecord::Base
  belongs_to :calendar
end

的routes.rb

resources :calendars do
  resources :content_items
end

控制器/ content_items_controller.rb

 def create
   @content_item = ContentItem.new(content_item_params)
   @calendar = Calendar.find(params[:calendar_id] )
   respond_to do |format|
     if @content_item.save
       format.html { redirect_to calendar_content_item_path(@calendar,@content_item), notice: 'Content item was successfully created.' }
       format.json { render :show, status: :created, location: @content_item }
     else
       format.html { render :new }
       format.json { render json: @content_item.errors, status: :unprocessable_entity }
     end
   end
 end

当我创建嵌套路由时,我在尝试创建新的content_items时开始遇到错误。每当我提交表单时,都会收到此错误:

  

ContentItems中的NoMethodError #create
  未定义的方法`content_items_path&#39;

错误来自: 的视图/ content_items / index.html.erb

<%= form_for [@calendar, @content_item] do |f| %>

更新 使用@Gaurav GuptA下面发布的代码修复了表单问题,但导致了新的错误。每当我访问/ calendars / 1 / content_items时,我都会收到错误 - 但只有在创建条目后才会收到错误。使用空数据库,它可以正常工作。

  

的ActionController :: UrlGenerationError   没有路由匹配{:action =&gt;&#34; show&#34;,:calendar_id =&gt;#,:controller =&gt;&#34; content_items&#34;,:format =&gt; nil,:id =&gt ; nil}缺少必需的键:[:id]

我相信这是因为在没有calendar_id的情况下保存了content_item。如何设置content_item以保存它所属的calendar_id?

更新2 它现在使用calendar_id保存,但是当保存项目时,edit / shpw / destroy的链接会抛出错误。

No route matches {:action=>"show", :calendar_id=>#<ContentItem id: 1, , content_type: "Test", content_text: "Tetst\r\n", calendar_id: 1, created_at: "2015-05-26 07:06:42", updated_at: "2015-05-26 07:06:42", content_image_file_name: nil, content_image_content_type: nil, content_image_file_size: nil, content_image_updated_at: nil>, :controller=>"content_items", :format=>nil, :id=>nil} missing required keys: [:id]

它突出显示了文件的这一部分:

<td><%= link_to 'Show', calendar_content_item_path(content_item) %></td>

GitHub链接:https://github.com/JeremyEnglert/baked

2 个答案:

答案 0 :(得分:2)

尝试将 content_items_controller 创建操作更改为:

 def create
   @calendar = Calendar.find(params[:calendar_id] )
   @content_item = @calendar.content_items.new(content_item_params) #Edit

   respond_to do |format|
     if @content_item.save
       format.html { redirect_to calendar_content_item_path(@calendar,@content_item), notice: 'Content item was successfully created.' }
       format.json { render :show, status: :created, location: @content_item }
     else
       format.html { render :new }
       format.json { render json: @content_item.errors, status: :unprocessable_entity }
     end
   end
 end

希望这对你有用。

答案 1 :(得分:2)

好的,你有路线:

resources :calendars do
  resources :content_items
end

例如,你得到一条这样的路径:

/calendars/50
/calendars/50/content_items/77

然后将其路由到:

app/controllers/calendars_controller.rb
app/controllers/content_items_controller.rb

您的错误来自create中的ContentItemsController操作。您要发布到该操作的参数包括您的日历ID "calendar_id"=>"1" 但没有什么可以收到它。 您需要获取与您正在创建的项目关联的Calendar实例。

@calendar = Calendar.find(params[:calendar_id] )

然后将@content_item传递保存到calendar_content_item_path(如路线中所示)两个对象:

format.html { redirect_to calendar_content_item_path(@calendar,@content_item), notice: 'Content item was successfully created.' }

ContentItemsController中的创建方法应如下所示:

 def create
   @calendar = Calendar.find(params[:calendar_id] )
   @content_item = @calendar.content_items.build(params[:content])
   respond_to do |format|
     if @content_item.save
       format.html { redirect_to calendar_content_item_path(@calendar,@content_item), notice: 'Content item was successfully created.' }
       format.json { render :show, status: :created, location: @content_item }
     else
       format.html { render :new }
       format.json { render json: @content_item.errors, status: :unprocessable_entity }
     end
   end
 end

我还注意到您将日历ID传递给强大的参数。这将通过错误,因为用户未分配日历的id。 您可以在Strong Parameters上阅读更多内容。