如何在Rails 3.1.3和Mongoid中为命名空间嵌套资源创建form_for?

时间:2011-12-13 04:44:52

标签: ruby-on-rails-3 mongoid

我是Rails的新手,正在尝试为移动应用创建Api。虽然Api会生成json响应,但我还需要一个Web界面来创建数据。我的路线看起来像这样:

Appone::Application.routes.draw do
  namespace :api1 do
    resources :reldates do
      resources :movies
    end
  end
end

release_date模型:

class Api1::Reldate
  include Mongoid::Document
  include Mongoid::MultiParameterAttributes
  include Mongoid::Timestamps

  field :release_date, :type => Date

  embeds_many :api1_movies
  validates_associated :movie
  accepts_nested_attributes_for :movie
end

电影模型:

class Api1::Movie
  include Mongoid::Document
  include Mongoid::MultiParameterAttributes
  include Mongoid::Timestamps

  field :title, :type => String
  field :release_type, :type => String
  field :release_number, :type => Integer

  embedded_in :api1_reldate, :inverse_of => :api1_movies
end

和reldate show.html.erb:

<p id="notice"><%= notice %></p>

<p>
  <b>Release date:</b>
  <%= @api1_reldate.release_date %>
</p>

<% if @api1_reldate.api1_movies.size > 0 %>
  <h2>Movies</h2>
  <% for api1_movie in @api1_reldate.api1_movies %>
    <h3><%= api1_movie.title %></h3>
    <p><%= api1_movie.release_type %></p>
    <p><%= api1_movie.release_number %></p>
  <% end %>
<% end %>

<h2>New Movies</h2>
<% form_for([:api1], :url => { :action => :create ,:id => @reldate.movie}) do |form| %>
  <p><%= f.label :title %> <%= f.text_field :title %></p>
  <p><%= f.label :release_type %> <%= f.text_field :release_type %></p>
  <p><%= f.label :release_number %> <%= f.number_field :release_number %></p>
  <p><%= f.submit %></p>
<% end %>

<%= link_to 'Edit', edit_api1_reldate_path(@api1_reldate) %> |
<%= link_to 'Back', api1_reldates_path %>

我无法让它发挥作用。我可以让reldate页面工作但是在我点击提交后,我收到这样的错误:

undefined method `movie' for nil:NilClass
Extracted source (around line #18):

15: <% end %>
16: 
17: <h2>New Movies</h2>
18: <% form_for([:api1], :url => { :action => :create ,:id => @reldate.movie}) do |form| %>
19:   <p><%= f.label :title %> <%= f.text_field :title %></p>
20:   <p><%= f.label :release_type %> <%= f.text_field :release_type %></p>
21:   <p><%= f.label :release_number %> <%= f.number_field :release_number %></p>

电影控制器如下所示:

class Api1::MoviesController < ApplicationController
def create
  @api1_reldate = Api1::Reldate.find(params[:api1_reldate_id])
  @api1_movie = @api1_reldate.api1_movies.create!(params[:api1_movie])
  redirect_to @api1_reldate, :notice => "Movie successfully created!"
end
end

我怎样才能让它发挥作用?我已经尝试了所有可能的解决方案,但它仍然失败。 另外,我正在使用Ryan Bates Railcast

提前致谢。

1 个答案:

答案 0 :(得分:0)

您正在接收undefined method 'movie' for nil:NilClass,因为您正在引用@ reldate.movi​​e并在控制器中分配@ api1_reldate。选一个。

另外,我不确定mongoid的需求是否不同,但AR使用数组作为命名空间路由和form_for:

来自:http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for

对于命名空间路由,例如admin_post_url:

<%= form_for([:admin, @post]) do |f| %>
 ...
<% end %>

我认为你需要:

form_for [:api1, Movie.new] do

您的代码示例显示您可能需要:

form_for [:api1, @reldate.movie] do

如果没有看到控制器,我无法判断@ reldate.movi​​e是否是一部新电影,但我对此表示怀疑。