通过Rails教程第3版由Michael Hartl完成:第8章登录,注销
我需要帮助理解为什么在session_controller中我们使用常规的'用户'在users_controller中我们使用' @ user'实例变量。
我注意到在session_controller中,我们使用
def create
user = User.find_by...
而在users_controller中,我们使用
def create
@user = User.new...
迈克尔说,"会话形式和注册表单之间的主要区别在于我们没有会话模型,因此没有@user变量的模拟..."指的是:
form_for(@user)
来自用户视图与
form_for(:session, url: login_path)
来自会话视图。
这有关系吗?我仍然不理解这一点。如果我需要更清楚或更具体,请告诉我。谢谢!
答案 0 :(得分:0)
def create
user = User.find_by...
在这种情况下,user
是一个局部变量。它只是在同一种方法中使用。
def create
@user = User.new...
这里,@user
是一个附加到UsersController
的实例变量,通过使其成为实例变量,可以在相应的视图中访问它。
因此,如果您查看与app/views/users
下的用户相关的任何观看次数,则会引用@user
。在与会话相关的视图(即app/views/sessions
文件夹下的视图文件)
答案 1 :(得分:0)
变量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
因此只能在视图中使用@user变量。 作者在session_controller中使用局部变量user,因为不需要在视图中使用此变量,并且他在users_controller上使用@user,因为如果用户验证失败,它将使用用户在提交之前输入的值呈现form_for(@user)格式。因此用户不必再次填写所有表单字段,他只需要修复错误的字段
答案 2 :(得分:0)
我仍然不理解这一点。如果我需要更清楚或更具体,请告诉我。
让我们试着了解所有这些事情是如何运作的:
在users_controller
中,您将@user = User.new
实例化一个空白用户对象,您将在注册表单中使用该对象。这样做的原因是,如果您实例化一个新对象并将该对象作为参数传递给表单,rails将自动调用users_controller
的create方法。由于Rails RESTful资源路由,事情将会完成。
在#create
期间,
<%= form_for(@user) do |f| %>
...
<% end %>
相当于:
<%= form_for @user, as: :user, url: users_path, html: { class: "new_user", id: "new_user" } do |f| %>
...
<% end %>
另一方面,如果您实例化@user = User.find(...)
之类的旧记录,则当您提交表单时,rails会调用#update
users_controller
方法。
在#update
期间,
<%= form_for @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 %>
那么,现在为什么sessions_controller
#create
行动中没有使用实例变量?好的,如果您实例化@user
对象并在登录表单中使用该对象,就像您在注册表单中所做的那样,它将调用#create
users_controller
的{{1}}行动,而不是#create
sessions_controller
。
这就是使用登录表单form_for(:session, url: login_path)
的原因。您将收到一个Hash
,其中包含:session
密钥,并且由于明确告知提交网址,即login_path
,因此登录信息将提交至#create
sessions_controller
行为}}
希望现在事情变得有意义了。