开发者

URL encoded route to Rails controller

开发者 https://www.devze.com 2022-12-18 13:14 出处:网络
I have a URL encoded resource such as: http://myurl/users/Joe%20Bloggs/index.xml This is for a RESTful webservice which uses user logins in the path.The problem is that the controller in rails doesn

I have a URL encoded resource such as:

http://myurl/users/Joe%20Bloggs/index.xml

This is for a RESTful webservice which uses user logins in the path. The problem is that the controller in rails doesn't seem to decode the %20. I get the following error:

ActionController::RoutingError (No route matches "/Joe%20Bloggs/index.xml" with {:method=>:post}):

What I'm actually trying to do is achieve one of 2 options (using authlogic as my registrations handler):

  • Either (preferably) allow users to register user names with spaces in them, and have these get routed correctly to my controller. Authlogic by default allows spaces & @/. characters - which is just fine with me if I can make it work...

  • Or I can restrict authlogic to dissallow the spaces. I know I can do this with:

    .merge_validates_format_of_login_fie开发者_高级运维ld_options...

but I'm not entirely sure of the correct syntax to provide the new regex and return message on failure...

Any suggestions greatly appreciated!


Generally it's a better idea to have a URL-safe "slug" field in your models for situations like this. For example:

class User < ActiveRecord::Base
  before_validation :assign_slug

  def to_param
    # Can't use alias_method on methods not already defined,
    # ActiveRecord creates accessors after DB is connected.
    self.slug
  end

  def unique_slug?
    return false if (self.slug.blank?)

    if (new_record?)
      return self.class.count(:conditions => [ 'slug=?', self.slug ]) == 0
    else
      return self.class.count(:conditions => [ 'slug=? AND id!=?', self.slug, self.id ]) == 0
    end
  end

  def assign_slug
    return if (slug.present?)

    base_slug = self.name.gsub(/\s+/, '-').gsub(/[^\w\-]/, '')
    self.slug = base_slug
    count = 1

    # Hunt for a unique slug starting with slug1 .. slugNNN

    while (!unique_slug?)
      self.slug = base_slug + count.to_s
      count += 1
    end
  end
end

This may solve the problem of having non-URL-friendly names. Rails is particularly ornery when it comes to having dots in the output of to_param.

0

精彩评论

暂无评论...
验证码 换一张
取 消