空字段上的路由错误,与Friendly_id冲突

发布于 2024-10-22 00:54:49 字数 1701 浏览 7 评论 0原文

我有一个@users 的编辑表单。 在那里我有一个 text_field :username

<%= form_for @user, :url => { :action => "update" } do |f| %>
 <%= render 'shared/error_messages', :target => f.object %>
 <div class="field">
    <%= f.label :username %><br />
    <%= f.text_field :username %>
 </div>

在我的用户模型中我使用amilies_id gem,也设置为 :username 。所以我的网址看起来像domain.com/users/:username 而不是:id。

has_friendly_id :username

现在,在我的应用程序布局中,我还在导航中使用 @user.username 链接到配置文件。

一切正常,除非我在保存时将 :username 字段留空。它无法保存验证原因,

validates :username, :presence => true, :uniqueness => { :case_sensitive => false }, :length => { :maximum => 50 }

并尝试再次呈现“编辑”。但要呈现“编辑”,我们需要用户名来在导航栏中创建链接。显然它是作为用户名 => 传递的“”,尽管它理所当然地未能保存并且已经进行了适当的验证。

 def update
  @user = current_user
  if @user.update_attributes(params[:user])
    flash[:success] = "Account updated."
    redirect_to :back
  else
    @title = "Edit"
    render "edit"
  end

所以我最终

得到了一个 RoutingError:

No route matches {:action=>"show", :controller=>"users", :id=>#<User id: 6, username: "", persistence_token: "c2f2545659c186131537155347f46f7da5eb0d51b27707e71da...", created_at: "2011-03-14 14:26:48", updated_at: "2011-03-15 01:54:33", email: "[email protected]", crypted_password: "0d6489b1447d278bc4f7c86bab13787f226a10a302b43ec02ff...", password_salt: "Lq2G80iSVeaitB5PDwf", perishable_token: "Tm7Jzyq8QutfaxL3JLZ8", active: true>}

I have a edit form for @users.
In there I have a text_field :username

<%= form_for @user, :url => { :action => "update" } do |f| %>
 <%= render 'shared/error_messages', :target => f.object %>
 <div class="field">
    <%= f.label :username %><br />
    <%= f.text_field :username %>
 </div>

In my User model I use the friendly_id gem, set to :username as well. So my urls look like domain.com/users/:username instead of :id.

has_friendly_id :username

Now in my application layout, I also use @user.username in my navigation to link to the profile.

All works well, EXCEPT if I leave my :username field empty on save. It fails to save cause of validations,

validates :username, :presence => true, :uniqueness => { :case_sensitive => false }, :length => { :maximum => 50 }

and tries to render "edit" again. But to render "edit" we need the username to create the link in the navbar. And apparently it's passed on as username => "", even though it rightfully so failed to save and proper validations are in place.

 def update
  @user = current_user
  if @user.update_attributes(params[:user])
    flash[:success] = "Account updated."
    redirect_to :back
  else
    @title = "Edit"
    render "edit"
  end

end

So I end up with a RoutingError:

No route matches {:action=>"show", :controller=>"users", :id=>#<User id: 6, username: "", persistence_token: "c2f2545659c186131537155347f46f7da5eb0d51b27707e71da...", created_at: "2011-03-14 14:26:48", updated_at: "2011-03-15 01:54:33", email: "[email protected]", crypted_password: "0d6489b1447d278bc4f7c86bab13787f226a10a302b43ec02ff...", password_salt: "Lq2G80iSVeaitB5PDwf", perishable_token: "Tm7Jzyq8QutfaxL3JLZ8", active: true>}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

短叹 2024-10-29 00:54:49

首先,即使您成功更改用户名,重定向到 :back 也可能会失败,因为 URL 本身会有所不同。所以你可能应该

redirect_to @user

这样做。

如果您想使用username字段作为Friendly_id的基础,那么最好不要让它为空,您可以通过向模型添加验证来强制执行:

class User < ActiveRecord::Base
  ...
  validates_presence_of :username
  ...
end

或者,如果对于某些因为在你的应用程序中将它们留空是有意义的,在这些情况下,你可以强制 Rails 根据数字 id 而不是Friendly_id 生成 URL。

为此,您需要将用户名值设置为 nil 而不是空白,然后执行

redirect_to @user

redirect_to user_url(@user)

在这种情况下,您还需要使用 :allow_nil => has_Friendly_id 的 true 选项。

我是FriendlyId的作者,如果这不能解决您的问题,请随时向FriendlyId的Google网上论坛或我本人发送消息,网址为[电子邮件受保护],我会尽力帮助您。

First of all, redirecting to :back, even if you successfully change the username, will likely fail because the URL itself is going to be different. So you should probably do

redirect_to @user

instead.

If you want to use the username field as the basis of a friendly_id, then it's probably best to not let it be blank, which you could enforce by adding a validation to the model:

class User < ActiveRecord::Base
  ...
  validates_presence_of :username
  ...
end

Alternatively, if for some reason in your app makes sense to have them blank, you can force Rails to generate the URL based on the numeric id rather than the friendly_id in these cases.

To do this, you would need to set username value to nil rather than blank, and then either do

redirect_to @user

or

redirect_to user_url(@user)

In this case you'll also want to use the :allow_nil => true option to has_friendly_id.

I'm the author of FriendlyId, if this doesn't solve your problem feel free to send a message to FriendlyId's Google Group or to me personally at [email protected], and I'll try to help you out.

dawn曙光 2024-10-29 00:54:49

如果验证失败,您实际上不需要重新渲染编辑屏幕。

如果您使用 ajax 更新页面并使用 remote_form_for (Rails 2) 或 form_for :remote => ,效果可能会更好。 true (Rails 3) 提交表单时。这样,如果您的表单通过了验证,您可以像您尝试做的那样重定向用户,但如果验证失败,您不需要实际离开页面,您只需将验证消息发送回表单即可。

Simone Carletti 的博客有一个关于如何做到这一点的相当不错的示例。

http://www.simonecarletti.com/blog/ 2010/06/unobtrusive-javascript-in-rails-3/

Ryan Bates 也提供了一个如何使用它的简单示例。

http://railscasts.com/episodes/205-unobtrusive-javascript

You don't really need to re-render the edit screen if your validation fails.

It'd probably work better if you updated your page using ajax and use a remote_form_for (Rails 2) or form_for :remote => true (Rails 3) when submitting your form. That way if your form passes the validation you can just redirect the user like you're trying to do, but you don't need to actually leave the page if your validation fails, you can just send the validation message back to the form.

Simone Carletti's blog has a pretty decent example on how to do it.

http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/

Ryan Bates has put up a simple example of how to use it as well.

http://railscasts.com/episodes/205-unobtrusive-javascript

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文