开发者

ActiveResource, a model, and Form_Tag

I am trying to use form_tag to pass the params captured by the form to my users controller. I am attempting to communicate with a Sinatra server, and so I do not have a database on the client. My view is as follows:

 <% form_tag(@user) do %>

<div class="field">
<%= label_tag :first_mame %><br />
<%= text_field_tag :first_name  %>
</div>
<div class="field">
<%= label_tag :last_name %><br />
<%= text_field_tag :last_name %>
</div>
<div class="field">
<%= label_tag :email %><br />
<%= text_field_tag "user[email]" %>
</div>
<div class="field">
  <%= label_tag :device_id %><br />
  <%= text_field_tag "user[device_id]" %>
</div>
<div class="field">
<%= label_tag :type %><br />
<%= text_field_tag "user[device_type]" %>
</div>
<div class="actions">
<%= submit_tag %>
 </div>
<% end %>

The create action on my controller is simply:

 def create
 @user = User开发者_StackOverflow中文版.new(params[@user])
 @user.save

respond_to do |format|
  if @user.save
    format.html { redirect_to(@user, :notice => 'User was successfully created.') }
    format.json {render :json => @user }
    format.xml  { render :xml => @user, :status => :created, :location => @user }
  else
    format.html { render :action => "new" }
    format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
  end
end

end

Here's what I get as a result => expected an attributes Hash, got nil

Anybody know why? Thanks for the help.


  1. You need to use form_for and not form_tag. form_for(@user) do
  2. In your model you need to create a schema. Without it Rails doesn't know what do with the data you enter into the form.
  3. When you pass the object into the parameter hash use :user and not @user. @user = User.new(params[:user])


For your form you need to do

<%= form_for @user do |f| %>
  <div class="field">
    <%= f.label :first_name %>
    <%= f.text_field :first_name %>
  </div>

  # more fields
<% end %>

Note the:

  • <% %> --> <%= %>
  • form_tag(@user) do --> form_for(@user) do |f|
  • label_tag --> f.label
  • text_field_tag --> f.text_field

In you controller:

@user = User.new(params[:user])

Update:

  • <% %> --> <%= %>: This is just the convention in rails3, when ever you want to write something in the response you should use later(with = sign). Earlier still works but is deprecated.

  • form_tag(@user) do --> form_for(@user) do |f|

    • form_tag(@user) do: form_tag is used to for simple forms which are not tied with any model. You can have the tags inside form_tag named so that they resemble form for, but then why wouldn't you use form_for directly. Apparently the first parameter to the helper is target url, and in this particular case rails magically identifies the url from @user and you didn't notice any bug
    • form_for(@user) do |f|: form_for is used to create a form for a model, and ties up the form with the instance of the model passed to it. The block for form_for receives a form_builder object, which has equivalents of text_field_tag, label_tag etc. as text_field, label
  • label_tag --> f.label: first is the common tag which just creates a label tag with no magic attached to it.The later is related with the model object and follows different naming and id conventions, than former. It also ties up with the value of the field, i.e. if the field has an error(failed validation), your label will be surrounded by a div tag with class fields_with_error or something, I can't remember the class name.

  • text_field_tag --> f.text_field: Former will create a field with name first_name with no magic attached. The later follows a naming convention, the input field will be named user[first_name], so that when you do params[:user] you get a first_name parameter there. It also ties up with the value of the field with the html input, i.e. you get the same error functionality as label and you also get the input automatically prefilled with whatever the value field has in the model instance.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜