form_for - Ruby on Rails

时间:2014-04-08 15:36:25

标签: ruby-on-rails ruby ruby-on-rails-4

我不理解 form_for

我尝试实现此tutorial,但我不理解视图代码 而且我不懂api,否则我不会在这里问。

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

  1. :as => :user 说什么?
  2. :url => sign_in_path很清楚,但为什么背后会有 (@user)
  3. 如何在其他@user中访问 View ? 3.1。我还想要application.html.erb(布局)中的登录表单,但@user位于user_controller.rb而不是application_controller.rb。 我怎么能这样做?
  4. <%= form_for (User.new), ...运作良好,但我认为这不对..
  5. 为什么有类似for / forEach-loop的东西? do |f| %>
  6. 感谢您的帮助!

1 个答案:

答案 0 :(得分:33)

一点解释( form_for documentation here):

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

第1点。 :as => :user

这是用于生成输入名称(以及参数名称)的名称,例如:

= form_for Admin.new, as: :user do |f|
                          #^^^^
  = f.input :username

# will generate an input like this:
<input type='text' name='user[username]' #... />
                        #^^^^

第2点。 :url => sign_in_path(@user)

在教程中,@user设置如下:

  def sign_in
    @user = User.new
  end

第3点。 @user可用于其他操作

您必须在您想要的每个操作中设置此变量。它可能是多余的,因此您可以使用before_filter来验证在您希望的每个操作中设置@user变量:

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

如果您想让它在您的应用中随处可用(暗示您必须连接到用户帐户才能浏览应用):

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

第4点。 form_for (User.new)

我们在控制器中设置变量@user并将其作为参数传递给form_for,因为它是一个Rails惯例,永远不会直接在视图中调用模型的名称,并且不推荐使用它视图中的SQL查询。

示例:

######## WRONG
# view
<%= Post.find(params[:id]).title %>

######## MUCH BETTER
# controller's action:
def show
  @post = Post.find(params[:id])

# view
<%= @post.title %>
在控件的操作中设置的

实例变量在操作,视图及其部分视图之间共享。


第5点。在form_for

中执行/结束

请在此时提供您的意见,不确定如何解释

这部分代码称为do / end块,它代表将在form_for的上下文中执行的一段代码。我们使用form_for的实例作为管道中定义的变量,这里是|f|。我通常不使用|f|,这与我无关。我更喜欢使用这种变量名称:

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

我认为这更容易理解。