Ruby on rails 在控制器中使用实例变量

Ruby on rails 在控制器中使用实例变量,ruby-on-rails,ruby,session,Ruby On Rails,Ruby,Session,使用Rails教程Michael Hartl编写的第三版:第8章登录,注销 我需要帮助理解为什么在会话控制器中使用常规的“user”变量,而在用户控制器中使用“@user”实例变量 我注意到在会话_控制器中,我们使用 def create user = User.find_by... 而在用户控制器中,我们使用 def create @user = User.new... Michael指出,“会话表单和注册表单之间的主要区别在于我们没有会话模型,因此没有@user变量的模拟

使用Rails教程Michael Hartl编写的第三版:第8章登录,注销

我需要帮助理解为什么在会话控制器中使用常规的“user”变量,而在用户控制器中使用“@user”实例变量

我注意到在会话_控制器中,我们使用

def create
    user = User.find_by...
而在用户控制器中,我们使用

 def create
   @user = User.new...
Michael指出,“会话表单和注册表单之间的主要区别在于我们没有会话模型,因此没有@user变量的模拟……”指的是:

form_for(@user)
从用户视图与

form_for(:session, url: login_path)
从会话视图

这有关系吗?我仍然不明白这一点。请让我知道,如果我需要更清楚或具体。谢谢大家!

def create
  user = User.find_by...
在这种情况下,
user
是一个局部变量。它只是在同一方法中使用

def create
  @user = User.new...
这里,
@user
是一个实例变量,附加到
userscocontroller
,通过将其设置为实例变量,可以在相应的视图中访问它


因此,如果您在
app/views/users
下查看与用户相关的任何视图,就会看到对
@user
的引用。在与会话相关的视图(即
app/views/sessions
文件夹下的视图文件)中不会执行此类操作。

变量user和@user具有不同的作用域

单词def end之间可用的用户变量

def create
  user = User.new
  print user
end
create 
print user 
NameError: undefined local variable ...
不能在方法定义块之外使用用户变量,但如果使用@user之类的变量,则可以

def create
  @user = User.new
  print @user
end
create 
print @user 
#<User:0x007fe1d25596d0>=> nil 
def创建
@user=user.new
打印@用户
结束
创造
打印@用户
#=>零
因此,视图中只能使用@user变量。 作者在会话\控制器中使用局部变量user,因为视图中不需要使用此变量,他在用户\控制器上使用@user,因为如果用户验证失败,它将使用用户在提交前输入的值呈现(@user)的表单\ u。所以用户不必再次填写所有表单字段,只需修复错误字段即可

我仍然不明白这一点。请让我知道,如果我需要更清楚或具体

让我们试着了解所有这些东西是如何工作的:

users\u controller
中,您正在通过
@user=user.new
实例化一个空白用户对象,您将在注册表中使用该对象。这样做的原因是,如果实例化一个新对象并将该对象作为参数以表单形式传递,rails将自动调用
users\u controller
的create方法。由于Rails RESTful资源路由,事情将得以完成。

在创建过程中

<%= form_for(@user) do |f| %>
  ...
<% end %>
<%= form_for @user do |f| %>
  ...
<% end %>
相当于:

<%= form_for @user, as: :user, url: users_path, html: { class: "new_user", id: "new_user" } do |f| %>
  ...
<% end %>
<%= form_for @user, as: :user, url: user_path(@user), method: :patch, html: { class: "edit_user", id: "edit_user_1" } do |f| %>
  ...
<% end %>

...
那么,现在为什么在
会话(u controller
#create
操作中不使用实例变量呢?好的,如果您实例化一个
@user
对象,并像在注册表单中那样在登录表单中使用它,它将调用
\create
用户控制器的操作,而不是
\create
会话控制器的操作

这就是为什么在登录表单
中使用(:session,url:login\u path)
的原因。您将收到一个
散列
,其中包含
:session
键,并且由于提交url被明确告知,即
登录路径
,登录信息将提交给
#创建
会话(控制器
的操作


希望现在一切都有意义。

“那么,为什么实例变量不在会话#控制器#创建操作中使用?好的,如果您实例化一个@user对象,并像在注册表中那样在登录表单中使用它,它将调用#创建用户#控制器的操作而不是#创建会话#控制器的操作。”您是说UsersController中定义的@user实例变量在views/users/之外的表单中可用吗?