Tag Archives: ror

Using form_tag and collection_select with Rails3

After being away from rails for a while, i’m coming back en version 3 to check it all out again.

I had a problem with how to create a simple select, using the FormHelper.

I had two models, a user and a customer. They are defined as follows:

class User < ActiveRecord::Base
  belongs_to :customer
end
class Customer < ActiveRecord::Base
  has_many :users
end

In my UserController I have an action called new, where I initialize a new user object and fetch all the customers from the database:

class UsersController < ApplicationController
  # Opens the new user view.
  def new 
    @user = User.new
    # fetches all the customers, ordered by their name
    @customers = Customer.order(:name)
  end
end

However, when I wanted to associate the new user and a customer I couldn't remember how this was done. Then I headed over to api.rubyonrails.com and found the FormHelper, which didn't help me much though...
Then I looked at the FormOptionsHelper, which has the method:
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})

In order to use this in my view, I had the following code:

<% form_for @user do |f| %>
<ul>
  <li>
    <%= f.label :customer %>
    <!-- select element here!-->
  </li>
  <li>
    <%= f.label :name %>:
    <%= f.text_field :name %>
  </li>
  <li>
    <%= f.label :email %>:
    <%= f.text_field :email %>
  </li>
  <li>
    <%= f.submit %>
  </li>
</ul>
<% end %>

The method states that it needs an object, a method, a collection, value, text. This resulted in the first try:

<li>
  <%= f.label :customer %>
  <% f.collection_select :user, :customer_id, @customers, :id, :name %>
</li>

Which gave a nice error...

This worked however:

<li>
  <%= f.label :customer %>
  <%= f.collection_select :customer_id, @customers, :id, :name %>
</li>

Why?
Well the form_tag was being done on the user object already, so the first object could be skipped.

Hope you can use it!

Using link_to in rails with :confirm and :method

Every time i’m going to use the link_to method in rails, I always seem to get a lot of errors.

The documentation states:

link_to(name, options = {}, html_options = nil)
link_to(options = {}, html_options = nil) do
# name
end

URL to the rails docs: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#M001597

And gives a list of options you can set. However, I always seem to have problems remembering the correct syntax if I want to use :confirm and :method.

After fiddling with it a bit, I found that the proper way of using is:

%lt%= link_to(
  t("Delete"), 
  {
    :action => "destroy",
    :id => some_id
  },
  :method => :delete,
  :confirm => t('Are you sure you want to delete it?')
) %>

My biggest problem was, that you do not need to add the controller.

Also, found a nice write up about this on Ryan’s Scraps blog (a bit old post, but still…)

Hope you can use the tip.

Use Rails’ form_tag with care

Today at work I was fiddling with some forms in an admin interface. When I had to make an update form, the data didn’t hit the correct controller action.

If you ever get the message ActionController::MethodNotAllowed, then you’ve created your form wrong!

The error came when I tried doing:

<% form_tag :action => :update, :method => :put do %>
  lots of fields here
<% end %>

The data was not sent correctly (it was sent as POST, not as PUT as I wanted) and the action was not found. After googling for a bit, I found out that others had a similar problem.

The answer was rather simple though. In the rails docs you use the form_tag like this:

form_tag(url_for_options = {}, options = {}, *parameters_for_url, &block)

What I didn’t realize straight away was, that my :method => put was being sent in the first hash and NOT the second as it was suppose to.
So if you are creating your own forms, without activerecord, do it like this:

<% form_tag({:action => :update}, {:method => :put}) do %>
  lots of fields here
<% end %>