RoutingError в пустом поле, конфликтует с friendly_id - PullRequest
0 голосов
/ 16 марта 2011

У меня есть форма редактирования для @users. Там у меня есть text_field: имя пользователя

<%= 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>

В моей модели User я использую гем friendly_id, также установлен: username. Так что мои URL выглядят как domain.com/users/:username вместо: id.

has_friendly_id :username

Теперь в макете приложения я также использую @ user.username в своей навигации для ссылки на профиль.

Все работает хорошо, КРОМЕ, если я оставлю поле: username пустым при сохранении. Не удалось сохранить причину проверок,

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

и снова пытается отредактировать «edit». Но чтобы сделать «правку», нам нужно имя пользователя, чтобы создать ссылку в навигационной панели. И, очевидно, он передается как username => "", даже если он по праву не был сохранен, и соответствующие проверки выполнены.

 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>}

Ответы [ 2 ]

1 голос
/ 16 марта 2011

Во-первых, перенаправление на: назад, даже если вы успешно измените имя пользователя, скорее всего не удастся, потому что сам URL будет другим. Так что вы, вероятно, должны сделать

redirect_to @user

вместо.

Если вы хотите использовать поле username в качестве основы для friendly_id, то, вероятно, лучше не оставлять его пустым, что можно было бы применить, добавив проверку в модель:

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

В качестве альтернативы, если по какой-то причине в вашем приложении есть смысл оставить их пустыми, вы можете заставить Rails генерировать URL-адрес на основе числового идентификатора, а не friendly_id в этих случаях.

Чтобы сделать это, вам нужно будет установить значение имени пользователя на nil вместо пустого, а затем либо сделать

redirect_to @user

или

redirect_to user_url(@user)

В этом случае вы также захотите использовать опцию :allow_nil => true для has_friendly_id.

Я являюсь автором FriendlyId, если это не решит вашу проблему, не стесняйтесь отправить сообщение в Группу друзей FriendlyId или мне лично по адресу norman@njclarke.com, и я постараюсь вам помочь.

0 голосов
/ 16 марта 2011

На самом деле вам не нужно повторно отображать экран редактирования, если ваша проверка не удалась.

Вероятно, будет лучше, если вы обновите свою страницу с помощью ajax и используете remote_form_for (Rails 2) или form_for: remote => true (Rails 3) при отправке вашей формы. Таким образом, если ваша форма проходит проверку, вы можете просто перенаправить пользователя, как вы пытаетесь сделать, но вам не нужно фактически покидать страницу, если ваша проверка не пройдена, вы можете просто отправить сообщение проверки обратно в форму.

В блоге Симоны Карлетти есть довольно приличный пример того, как это сделать.

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

Райан Бейтс привел простой пример того, как его использовать.

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

...