开发者

Rails 3 Routing: Using 2 dynamic segments in path for one model

开发者 https://www.devze.com 2023-03-30 12:30 出处:网络
What I am trying to achieve is something similar to Github\'s way for routes. E.g. I have a project with the name \'question\' results in the URL /hjuskewycz/question. So my goal is to have routes whe

What I am trying to achieve is something similar to Github's way for routes. E.g. I have a project with the name 'question' results in the URL /hjuskewycz/question. So my goal is to have routes where the first segment is the username and the second the project's name.

I tried a couple of different approaches, this is the one I am stuck with right now:

scope ":username" do
    resources :projects, :path => "" do
        resources :pictures
    end
end

Using

project_path :username => project.owner.username, :id => project.to_param

works as expected. However, it's tedious to always specify the username although it's always the owner's username. I would very much prefer

project_path(:id => project.to_param)

I know about default_url_options and url_for and 开发者_StackOverflowI digged in the code. However, polymorphic_url doesn't use default_url_options.

I tried in routes.rb:

resources :projects, :path => "", :defaults => {:username => Proc.new { "just_testing" }}

since you can use a proc for constrains, but haven't got it working either.

I tried in project.rb

def to_param
    "#{owner.username"/#{project.title}"
end

I spent already too much time on this problem and my current approach uses a convenience method to add the :username parameter. Nevertheless, I think using this method all over the place just to add an entry stinks (bad code smell). I wonder if there is a more elegant solution to this problem.


I think you should not make things complicated here, just use something like this:

In Routes.rb

match ':username/:projectname/' => 'projects#show_project' , :as => :show_project

and in project_controller, just define this

def show_project

  @user =User.find_by_username(params[:username])
  @project =Project.find_by_slug(params[:projectname])

end

Simpler is better, it saves time and easy to understand for others


You want to do something like this in your controller:

before_filter :set_username

def set_username
  Rails.application.routes.default_url_options[:username] = @user.name
end
0

精彩评论

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