工作通过Rails教程第3版,由Michael :CH8登录,注销
我需要帮助理解为什么在session_controller中我们使用常规的'user‘变量,而在users_controller中我们使用'@user’实例变量。
我注意到在session_controller中,我们使用
def create
user = User.find_by...
而在users_controller中,我们使用
def create
@user = User.new...
Michael说,“会话表单和注册表单之间的主要区别是,我们没有会话模型,因此@user变量没有模拟.”提到这一点:
form_for(@user)
从用户视图与
form_for(:session, url: login_path)
在会话视图中。
这有关系吗?我还是不明白这一点。如果我需要说得更清楚或者更具体,请告诉我。谢谢!
发布于 2015-03-12 13:31:22
def create
user = User.find_by...
在这种情况下,user
是一个局部变量。它只是在相同的方法中使用。
def create
@user = User.new...
在这里,@user
是一个附加到UsersController
的实例变量,通过使它成为实例变量,可以在相应的视图中访问它。
因此,如果您查看与app/views/users
下的用户相关的任何视图,就会有对@user
的引用。在与会话相关的视图(即app/views/sessions
文件夹下的视图文件)中,没有任何此类操作。
发布于 2015-03-12 13:52:06
变量user和@user有不同的作用域
用户变量在单词def结束之间可用
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 ),其中包含用户在提交之前输入的值。因此,用户不必再填写所有表单字段,他只需修复错误的字段即可。
发布于 2015-03-12 14:33:21
我还是不明白这一点。如果我需要说得更清楚或者更具体,请告诉我。
让我们试着理解所有这些事情是如何运作的:
在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将调用users_controller
的#update
方法。
在#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
对象并在登录表单中使用它,就像您在注册表单中所做的一样,它将调用users_controller
的#create
操作,而不是sessions_controller
的#create
操作。
这就是为什么在登录表单中使用form_for(:session, url: login_path)
的原因。您将收到一个带有Hash
键的:session
,并且由于提交url被显式告知,即login_path
,登录信息将提交给sessions_controller
的#create
操作。
希望现在一切都有意义了。
https://stackoverflow.com/questions/29020401
复制