简体   繁体   中英

form_for - Ruby on Rails

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 the api, otherwise I wouldnt asked here..

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

  1. What does the :as => :user say ?
  2. :url => sign_in_path is clear, but why is there a (@user) behind it?
  3. And how can I get access to @user in a different View ?
    3.1. I also want the log-in-form in the application.html.erb (the layout), BUT the @user is in the user_controller.rb and not in the application_controller.rb .
    How can I do this?
  4. <%= form_for (User.new), ... works well, but I think it isn't right..
  5. Why is there something like a for/forEach-loop? do |f| %>

Thanks for your help!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM