0

Rails 大师的简单问题。为什么我必须在我的 VideosController 的以下创建方法中使用以下语句插入新的 Mongoid 文档:params[:video][:description]?为什么我不能使用 POST 表单中的 params[:description]?如果我使用它,该值将变为 nil。

def create
    @video = Video.new(
        :title => params[:video][:title],
        :description => params[:video][:description]
    )
    if @video.save
        render 'success'
    else
        render 'error'
    end
end

这是 Video.rb 类:

class Video
    include Mongoid::Document

    field :title, type: String
    field :description, type: String

    validates_presence_of :title
    validates_presence_of :description

    acts_as_url :title
end

最后是表单视图:

<%=  form_for @video do |f| %>

    <%= f.label :title %>
    <%= f.text_field :title %>

    <p/>

    <%= f.label :description %>
    <%= f.text_field :description %>

    <%= submit_tag("Enqueue video") %>

<% end %>

我不太明白为什么表单输入是 video[description] 而不仅仅是预期的描述:

<label for="video_title">Title</label>
<input id="video_title" name="video[title]" type="text" />

<p/>

<label for="video_description">Description</label>
<input id="video_description" name="video[description]" type="text" />
4

2 回答 2

2

当您使用时form_for

创建一个表单,允许用户创建或更新特定模型对象的属性。

在你的情况下,Video模型。要了解 Rails 约定:

<%=  form_for @video do |f| %>
...
<%= f.text_field :description %>
...

这会产生一个名称属性为video[description]的 html 标记。这意味着当提交表单时,用户输入的值将在控制器中作为params[:video][:description]可用。

根据文档,该params变量是 的一个实例ActiveSupport::HashWithIndifferentAccess,就像 aHash有很小的区别:

这个类有可疑的语义,我们只有这样才能让人们写params[:key]而不是params['key']并且他们为两个键获得相同的值。

params是这样的:

{"utf8"=>"✓",
 "_method"=>"post",
 "authenticity_token"=>"xxx",
 "video"=>
  {"description"=>"Video desc"}
}

其中"video"或是:video哈希的键之一。所以,params[:video]相当于params.fetch("video")哪个值是{"description"=>"Video desc"}。如您所见,该值是另一个哈希。最后要获得描述的值,你必须params[:video][:description](Rails 方式)或params.fetch("video").fetch("description"),哪个值是"Video desc".

fetch是一种 Ruby 方法Hash:“从给定键的哈希中返回一个值。”

考虑到这一点:

Video.new(params[:video]) = Video.new(:description => "Video desc") = Video.new(:description => params[:video][:description])

使用约定更容易,但可以肯定的是params[:description](以防万一):

<%=  form_for @video do |f| %>
...
<%= text_field_tag :description %>
...

请注意,我使用text_field_tag的是f.text_field. 在这种情况下,html标签名称将descriptionparams您将收到的哈希中{ "description" => 'Video desc" }...

查看Rails API 文档以了解不同的帮助程序等。还可以查看服务器的日志。

于 2013-08-30T20:13:17.013 回答
0

如果你想使用视频[:description]。像这样创建您的表单

<%=  form_for @video do |f| %>

   ....

    <p/>

    <%= f.label :description %>
    <%= f.text_field :description, :name => "description" %>

   ....

<% end %>

Rails form_for helper 命名输入元素,以便像这样将它们一次性推送到模型属性中变得容易

@video = Video.new(params[:video])

这样您就不必像以前那样做

@video = Video.new(
        :title => params[:video][:title],
        :description => params[:video][:description]
    )
于 2013-08-25T05:29:06.873 回答