form_for - Ruby on Rails form_for - Ruby on Rails ruby-on-rails ruby-on-rails

form_for - Ruby on Rails


A little explanation ( form_for documentation here):

<%= form_for @user, :as => :user, :url => sign_in_path(@user) do |f| %>

Point 1. :as => :user

This is the name used to generate the input's name (and the params' names), example:

= form_for Admin.new, as: :user do |f|                          #^^^^  = f.input :username# will generate an input like this:<input type='text' name='user[username]' #... />                        #^^^^

Point 2. :url => sign_in_path(@user)

In the tutorial, @user is set like this:

  def sign_in    @user = User.new  end

Point 3. @user available in other actions

You have to set this variable in each action you want it. It can be redundant, so you can use a before_filter in order to authenticate set the @user variable at each action your want:

class UsersController < ApplicationController  before_filter :set_user_variable  def set_user_variable    @user ||= User.find(session[:user_id]) if session[:user_id].present?  endend

If you want to make it available everywhere in your app (implies that you must be connected to a user account to browse the app):

class ApplicationController < ActionController::Base  before_filter :set_user_variable, except: [:sign_in, :login]  def set_user_variable    @user ||= User.find(session[:user_id]) if session[:user_id].present?  end

Point 4. form_for (User.new)

We set the variable @user in the controller and pass it as an argument to form_for because it is a Rails Convention to never call a Model's name directly in the views, and it is deprecated to provoke SQL queries in the view.

Example:

######## WRONG# view<%= Post.find(params[:id]).title %>######## MUCH BETTER# controller's action:def show  @post = Post.find(params[:id])# view<%= @post.title %>

Instance Variables set in the Action of a Controller are shared between the actions, its view and its partial views.


Point 5. do/end block in form_for

Please give your input at this point, not sure how to explain it

This part of the code is called a do/end block, it represents a piece of code that will be executed in the context of the form_for. We use the form_for's instance as the variable defined in the pipes, here it is |f|. I usually don't use |f|, it is not really relevant to me. I prefer to use this kind of variable name:

= form_for @user do |user_form_builder|  = user_form_builder.input :username

Which I think is more readable and easier to understand.