渲染视图问题
他们是两个用户:
用户 - 登录用户
访客 - 未登录访客。
用户和访客可以发布问题。要发布问题,客人必须指定他的电子邮件。
它们是两个视图“new.html.erb”和“new_for_guest.html.erb”。第一个依赖于 @user 变量。第二个则不然。
当访客创建的问题验证失败时,应呈现“new_for_guest.html.erb”,保留所有输入的数据。
代码如下:
def new
@question = Question.new
guest = session[user_id].nil?
respond_to do |format|
if guest
format.html { render "new_for_guest" }
else
format.html { render "new" }
end
end
end
def create
@question = Question.new(params[:question])
guest = session[user_id].nil?
respond_to do |format|
if @question.save
flash[:notice] = 'Question was successfully created.'
format.html { redirect_to(@question) }
else
if guest
format.html { render :action => "new_for_guest" } # problem
else
format.html { render :action => "new" }
end
end
end
当访客验证失败并且呈现“new_for_guest”视图时,我在浏览器中看到网址“/questions”,而不是“/questions/new”。因此,用于“新”操作的所有样式表都消失了。
当用户验证失败并且呈现“新”视图时,我看到正确的网址“/questions/new”,一切正常。
当我刚刚说
format.html{ redirect_to new_question }
“新”操作将被呈现时,但用户输入的所有数据都消失了。
我需要在“问题/新”上下文中渲染“new_for_guest”视图。
怎么办呢?
更新
我注意到由脚手架生成的未触及代码的相同行为。
当创建时,验证失败,新的操作会再次呈现,但在 URL 中,显示“/questions”而不是“/questions/new”。
这很奇怪。这是正确的行为吗?
我发现类似的未解答问题Rails 创建操作在应该呈现新操作时重定向到索引
They are two users:
User - logged in user
Guest - not logged in visitor.
User and guest can post a question. To post a question, guest must specify his email.
They are two views "new.html.erb" and "new_for_guest.html.erb". The first one relies to @user variable. The second one does't.
When question, being created by guest, fails validation, "new_for_guest.html.erb" should be rendered, preserving all the entered data.
The code is following:
def new
@question = Question.new
guest = session[user_id].nil?
respond_to do |format|
if guest
format.html { render "new_for_guest" }
else
format.html { render "new" }
end
end
end
def create
@question = Question.new(params[:question])
guest = session[user_id].nil?
respond_to do |format|
if @question.save
flash[:notice] = 'Question was successfully created.'
format.html { redirect_to(@question) }
else
if guest
format.html { render :action => "new_for_guest" } # problem
else
format.html { render :action => "new" }
end
end
end
When validation fails for guest and "new_for_guest" view is rendered, i see in browser the url "/questions", instead of "/questions/new". Because of this, all the stylesheets, used for "new" action are gone.
When validation fails for user and "new" view is rendered, i see the correct url "/questions/new" and everything is ok.
When i just say
format.html{ redirect_to new_question }
"new" action will be rendered, but all the data, user has entered, is gone.
I need to render "new_for_guest" view in "questions/new" context.
How to do it ?
Update
I noticed the same behaviour of untouched code, generated by scaffold.
When by creation, validation is failed, new action is rendered again, but in URL, "/questions" is presented instead of "/questions/new".
This is strange. Is this a correct behaviour ?
I've found similar unanswered question Rails create action is redirecting to index when it should be rendering the new action
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是正确的行为。根据 RESTful 路由,当对象的表单被 POST 时,它会被发送到
/object
URI,这意味着创建了一个具有未知 ID 的新对象。 Rails 指南中对此进行了描述。因此,当验证失败并且您只需渲染新操作时,您将使用该 URI,而不是/object/new
URI。此外,您不应该让每个操作都具有特定的样式,因为那里肯定会有不需要的代码冗余(而且我什至不确定您是如何做到这一点的,这样当 URI 更改时它就不起作用)。对于一个操作有多个视图也是如此,这很少是绝对必要的,而且在您的情况下似乎也不是这样,因为当它是访客时您可以简单地使用一个空的
@user
对象。This is the correct behavior. As per RESTful routes, when a form is POSTed for an object it is sent to the
/object
URI, implying the creation of a new object with an unknown ID. This is described in the Rails Guides. As a result when validation fails and you simply render the new action, you are on that URI rather than the/object/new
URI.Further, you shouldn't have your styles be specific per action, as there will certainly be unneeded code redundancy there (and I'm not even sure how you're doing this such that it doesn't work when the URI changes). The same goes with having multiple views for an action, it is rarely absolutely necessary, and it doesn't appear it is in your case since you can simply utilize an empty
@user
object when it's a guest.