【问题标题】:RoutingError on empty field, conflicting with friendly_id空字段上的 RoutingError,与friendly_id 冲突
【发布时间】:2011-03-15 22:22:28
【问题描述】:

我有一个@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>

在我的用户模型中,我使用了friendly_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: "test@test.com", crypted_password: "0d6489b1447d278bc4f7c86bab13787f226a10a302b43ec02ff...", password_salt: "Lq2G80iSVeaitB5PDwf", perishable_token: "Tm7Jzyq8QutfaxL3JLZ8", active: true>}

【问题讨论】:

    标签: ruby-on-rails validation friendly-id


    【解决方案1】:

    首先,即使您成功更改了用户名,重定向到 :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)
    

    在这种情况下,您还需要对has_friendly_id 使用:allow_nil =&gt; true 选项。

    我是 FriendlyId 的作者,如果这不能解决您的问题,请随时向 FriendlyId 的 Google 群组或我本人发送邮件至 norman@njclarke.com,我会尽力帮助您。

    【讨论】:

      【解决方案2】:

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

      如果您使用 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

      【讨论】:

        猜你喜欢
        • 2011-06-12
        • 1970-01-01
        • 1970-01-01
        • 2011-06-07
        • 1970-01-01
        • 2017-10-02
        • 2021-11-29
        • 2022-10-24
        • 1970-01-01
        相关资源
        最近更新 更多