Подтвердить что ты не робот

Rails REST маршрутизация: точки в идентификаторе элемента ресурса

У меня есть следующие маршруты на моих маршрутах. rb:

resources :users, :except => [:new, :create] do
    get 'friends', :as => :friends, :on => :member, :to => "users#friends"
end

и следуя в моем user.rb:

def to_param
  self.login
end

И когда, например, пользователь с точками входа (например, "any.thing" ) приходит из facebook, rails дает ошибку маршрутизации (никакого маршрута не найдено, я полагаю, потому что он распознает что-либо после точки в виде формата или потому, что ограничений маршрута). Как я могу преодолеть эту ошибку?

4b9b3361

Ответ 1

Вы можете заменить периоды на другой символ:

def to_param
  login.gsub(/\./,"-") # note: 'self' is not needed here
end

user = User.find_by_login("bart.simpson")
user_path(user) # => "/users/bart-simpson"

ИЗМЕНИТЬ

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

  match 'users/(:id)' => 'users#show', 
    :constraints => { :id => /[0-9A-Za-z\-\.]+/ }

Это должно позволить "/users/bart-simpson" и /users/bart.simpson" генерировать :id => "bart-simpson" и :id => "bart.simpson" соответственно. Вам нужно будет изменить регулярное выражение, чтобы добавить все допустимые символы для URL.

Обратите внимание, что это упоминается в Rails Routing Guide, раздел 3.2:

По умолчанию динамические сегменты не принимают точки - это потому, что dot используется как разделитель для отформатированных маршрутов. Если вам нужно использовать точка в динамическом сегменте добавляет ограничение, которое отменяет это - например: id = > /[^/] +/позволяет что угодно, кроме косой черты.

Ответ 2

Следующее определение ограничения разрешает точку в id, а также любой символ, кроме слэша.

Поддерживаемые форматы должны быть явно определены (здесь .html и .json), чтобы они не были приняты идентификатором.

resources :foobars,
  :constraints => { :id => /[^\/]+(?=\.html\z|\.json\z)|[^\/]+/ }

Это ограничение определяет работу с Rails 3.1

Для более ранних версий Rails вам может потребоваться обратная поддержка вперед-назад в regin gem (она продается в стойке)

Ответ 3

Чтобы разрешить сегменту :id содержать любой символ, кроме '/':

match 'users/(:id)' => 'users#show', :constraints => {:id => /[^\/]+/}

Это написано в другом месте в одном из ответов, но это ИМО самый простой способ.