如何维护相同的控制器和控制器?在 Rails 中重新渲染操作时页面 URL 中的操作?
我正在使用 AuthLogic 对 Rails 应用程序中的用户进行身份验证。该部分已设置并正常工作。
我定义了以下路由:
map.login '/account/login', :controller => :user_sessions, :action => :new
调用 rake 路由会返回我期望的结果:
login /account/login {:controller=>"user_sessions", :action=>"new"}
当有人提交登录时,它会调用 UserSessionsController.create:
def create
@user_session = UserSession.new(params[:user_session])
if @user_session.save
flash[:notice] = "Login successful!"
redirect_back_or_default account_url
else
render :action => :new
end
end
如果 @user_session.save 失败,屏幕上会显示相应的错误消息。但是,浏览器 URL 也会更改为“http://localhost:3000/user_session”,而不是停留在“http://localhost:3000/account/login”。
我认为问题出在我向渲染方法提供的内容上。我应该给它喂什么?
I am using AuthLogic to authenticate users in my rails app. That part is set up and workign properly.
I have the following route defined:
map.login '/account/login', :controller => :user_sessions, :action => :new
Calling rake routes returns what I expect:
login /account/login {:controller=>"user_sessions", :action=>"new"}
When someone submits a login, it calls UserSessionsController.create:
def create
@user_session = UserSession.new(params[:user_session])
if @user_session.save
flash[:notice] = "Login successful!"
redirect_back_or_default account_url
else
render :action => :new
end
end
If @user_session.save fails, the appropriate error messages appear on the screen. However, the browser URL also changes to "http://localhost:3000/user_session" instead of staying on "http://localhost:3000/account/login".
I assume the problem is what I am feeding to the render method. What should I be feeding it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这实际上是此过程的预期行为。在标准的脚手架 RESTful 控制器中,
create
和update
操作中的验证错误将仅呈现原始模板而不进行重定向。这将导致您所看到的结果 –new
模板将与 URL 栏中的create
操作的 URL 一起显示。原因是,为了向用户显示有关发生的错误的信息,视图必须有权访问无效的模型对象,在您的情况下为@user_session
。如果您想强制重定向到原始 URL,可以使用
redirect_to
而不是render
,但这会导致您丢失有关错误的信息。您需要手动将错误保留在会话中,这会很混乱。我的建议是不要担心 URL 与原始 URL 不匹配,因为这在所有 Rails 应用程序中都是相当标准的。This is actually the intended behavior for this process. In a standard scaffolded RESTful controller, a validation error in the
create
andupdate
actions will simply render the original template without redirecting. This results in what you are seeing – thenew
template will be displayed with thecreate
action's URL in the URL bar. The reason for this is that in order to display information to the user about what errors occurred, the view must have access to the invalid model object, which is@user_session
in your case.You can use
redirect_to
instead ofrender
if you want to force a redirect to the original URL, but this will cause you to lose information about the errors. You would need to manually persist the errors in the session, which would be messy. My advice is not to worry about the fact that the URL doesn't match that of the original as this is pretty standard in all Rails apps.只需添加 Rails 4 的解决方案(基于此处 Shaun 的答案):
将新路线添加到路线文件:
post '/carts/new' => 'carts#create', as: :create_post
添加 url: create_post_path 到表单标签
完成。
Just adding solution for Rails 4 (based on Shaun's answer here):
Add new route to routes file:
post '/carts/new' => 'carts#create', as: :create_post
Add url: create_post_path to form tag
Done.
经过进一步挖掘,我在另一个 StackOverflow 问题中找到了解决方案: 在模型上使用自定义路由验证失败
我只是修改了我的路线,添加了一条新路线以摆在“/account/login”上:
然后,我更新了我的视图以利用新路线:
<% form_for @user_session, :url => login_post_path 执行 |f| %>
这非常有效。登录失败会给出相应的错误消息并维护“/account/login”URL。
After further digging, I found the solution in another StackOverflow question: Use custom route upon model validation failure
I simply modified my routes to add a new one for posing to '/account/login':
Then, I updated my view to utilize the new route:
<% form_for @user_session, :url => login_post_path do |f| %>
This works perfectly. A failed login gives the appropriate error messages and maintains the '/account/login' URL.