I do not understand the form_for
.
I try to implement this tutorial and I do not understand the view-code.
Moreover I dont understand th
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?
end
end
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.