user390749
user390749

Reputation:

RoR : Mongoid and form create hash

Simple question for Rails gurus. Why I do have to use the following statement to insert a new Mongoid document : params[:video][:description] in the following create method of my VideosController? Why I can't use the params[:description] from the POST form? If I use it, the value becomes nil.

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

Here is the Video.rb class :

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

And finaly the form view :

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

I don't quite get why the form input are video[description] and not just description as expected :

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

Upvotes: 0

Views: 798

Answers (2)

cortex
cortex

Reputation: 5206

When you are using form_for:

Creates a form that allows the user to create or update the attributes of a specific model object.

In your case, Video model. To understand Rails convention:

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

Which results in an html tag whose name attribute is video[description]. This means that when the form is submitted, the value entered by the user will be available in the controller as params[:video][:description].

The params variable is an instace of ActiveSupport::HashWithIndifferentAccess, like a Hash with a small difference, according to documentation:

This class has dubious semantics and we only have it so that people can write params[:key] instead of params[‘key’] and they get the same value for both keys.

Your params is something like:

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

Where "video" or :video is one of the keys of the Hash. So, params[:video] is equivalent to params.fetch("video") which value is {"description"=>"Video desc"}. As you can see the value is another Hash. Finally to get the value of the description you have to params[:video][:description] (The Rails way) or params.fetch("video").fetch("description"), which value is "Video desc".

fetch is a Ruby method of Hash: "Returns a value from the hash for the given key."

Taking this into account:

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

It's easier to use conventions, but for sure you can have params[:description] (just in case):

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

Note that I'm using text_field_tag instead of f.text_field. In this case the html tag name will be description in the params Hash you will receive { "description" => 'Video desc" }...

Take a look to Rails API documentation to understand different helpers, etc. And also review your server's log.

Upvotes: 2

techvineet
techvineet

Reputation: 5111

If you want to use video[:description]. Create your form like this

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

   ....

    <p/>

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

   ....

<% end %>

Rails form_for helper name the input elements such that it becomes easy to push them into model attributes in one go like this

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

so that you don't have to do it like the way you have done

@video = Video.new(
        :title => params[:video][:title],
        :description => params[:video][:description]
    )

Upvotes: 0

Related Questions