Rails REST routing: dots in the resource item ID

本小妞迷上赌 提交于 2019-11-27 15:54:33

问题


I have following in my routes.rb:

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

and following in my user.rb:

def to_param
  self.login
end

And when, for example, user with dots in login (for example 'any.thing') comes from facebook, rails gives routing error (no route found, I suppose that's because it recognises anything after dot as a format or because of route constraints). How can I come over this error?


回答1:


You could replace periods with another character:

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"

EDIT

You're right, this fails to deal with unique logins that map to the same value. Maybe a better way is to use segment constraints in the route:

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

This should allow "/users/bart-simpson" and /users/bart.simpson" to generate :id => "bart-simpson" and :id => "bart.simpson" respectively. You'd have to alter the regex to add all the acceptable characters for the URL.

Note that this is mentioned in the Rails Routing Guide, section 3.2:

By default dynamic segments don’t accept dots – this is because the dot is used as a separator for formatted routes. If you need to use a dot within a dynamic segment add a constraint which overrides this – for example :id => /[^\/]+/ allows anything except a slash.




回答2:


The following constrain definition permit the dot in id as well as any character except slash.

Supported formats must be explicitly defined (here .html and .json) to not to be taken by id.

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

That constrain definition is worked with Rails 3.1

For earlier Rails versions you may need to backport look-ahead support in regin gem (it is vendored in rack-mount gem)




回答3:


To allow the :id segment to contain any character except '/':

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

It's written elsewhere in one of the answers, but this is IMO the simplest way.



来源:https://stackoverflow.com/questions/5222760/rails-rest-routing-dots-in-the-resource-item-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!