RoR:Mongoid和表单创建哈希

时间:2013-08-25 03:19:15

标签: ruby-on-rails mongodb mongoid

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

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 %>

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

<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" />

2 个答案:

答案 0 :(得分:3)

使用form_for时:

  

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

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

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

这导致html标记的名称属性为视频[描述] 。这意味着当提交表单时,用户输入的值将在控制器中以 params [:video] [:description] 的形式提供。

根据文档显示,params变量是ActiveSupport::HashWithIndifferentAccess的一个实例,就像Hash一样,差异很小:

  

这个类有可疑的语义,我们只有这样的人才   可以写 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"

fetchHash的Ruby方法:“返回给定键的哈希值。”

考虑到这一点:

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标记名称将为description哈希,您将收到params ...

查看Rails API documentation以了解不同的助手等。并查看服务器的日志。

答案 1 :(得分: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]
    )