# Routes.recognize\_path on more complicated Routes

**URL:** <https://www.ruby-forum.com/t/routes-recognize-path-on-more-complicated-routes/162191>\
**Category:** Rails\
**Created:** [March 6, 2009, 3:56pm UTC](https://www.ruby-forum.com/t/routes-recognize-path-on-more-complicated-routes/162191 "2009-03-06T15:56:08Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dannytip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@dannytip](https://www.ruby-forum.com/u/dannytip)\
**Post date:** [March 6, 2009, 3:56pm UTC](https://www.ruby-forum.com/t/routes-recognize-path-on-more-complicated-routes/162191/1 "2009-03-06T15:56:08Z")

</div>

For a permissions system i’m writing i’m extending the standard link\_to  
helpers to check if a user has a permission to perform that action  
before displaying a link to clean-up my code so i don’t have to put if  
checks all over them.

I’m trying to use…

ActionController::Routing::Routes.recognize\_path(url, :method =\> method)

to get the action and controller out so i can check those permissions.

The problem im having is when it comes to more complicated routes the  
recognize\_path method gets things mixed up e.g.

/admin/users/60/edit - Controller: admin/users | Action: 60 | Id: edit -  
Correct  
/admin/users/60 - Controller: admin/users | Action: destroy | Id: 60 -  
Correct  
/admin/users/60/ban - Controller: admin/users | Action: 60 | Id: ban -  
Incorrect

As you see the ban link has the action and id the wrong way round.

Is there a correct way around this rather than just swapping the 2  
values round?

Also when doing a nested route like…

ActionController::Routing::Routes.recognize\_path("/admin/chat\_rooms/15/quick\_chats/new")

It errors saying “Only get, put, and delete requests are allowed.” even  
though that route works perfectly fine in a view.

The projects currently running on rails 2.0.1 if that helps.

Danny

---

<div class="post-metadata">

**Author:** ![dannytip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@dannytip](https://www.ruby-forum.com/u/dannytip)\
**Post date:** [March 16, 2009, 3:47am UTC](https://www.ruby-forum.com/t/routes-recognize-path-on-more-complicated-routes/162191/2 "2009-03-16T03:47:56Z")

</div>

Hi Danny,

good to see that someone is trying to achieve EXACTLY the same thing  
like me. I have even tried to dig deep in the link\_to implementation to  
solve this, but it is more than black magic and I soon gave up. Do you  
have any new ideas regarding the problem?

Jakub

---

<div class="post-metadata">

**Author:** ![dannytip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@dannytip](https://www.ruby-forum.com/u/dannytip)\
**Post date:** [March 16, 2009, 10:25am UTC](https://www.ruby-forum.com/t/routes-recognize-path-on-more-complicated-routes/162191/3 "2009-03-16T10:25:49Z")

</div>

Hi Jakub

Here’s the implementation i ended up with. Its not very clean but it  
does the job.

[code] def link\_to(\*args, &block)  
unless params[:controller] =~ /admin/  
super  
else  
if args.size \> 2  
super if action\_allowed(args[1], args[2][“method”])  
else  
super if action\_allowed(args[1])  
end  
end  
end

def link\_to\_remote(name, options = {}, html\_options = nil)  
unless params[:controller] =~ /admin/  
super  
else  
super if action\_allowed(options[:url], options[:method])  
end  
end

def action\_allowed(url, method = :get)  
return false unless current\_user

```
path = ActionController::Routing::Routes.recognize_path(url, :method 

```

=\> method) rescue nil

```
return true unless path

return true if current_user.roles.find(:first, :conditions => 

```

[“unrestricted = ?”, true])

```
permissions = Permission.find(:all, :conditions => ["role_id in 

```

(?)", current\_user.roles.map(&:id)])

```
if path[:action] =~ /^\d+$/
  perm = permissions.select { |p| p.controller == path[:controller] 

```

&& p.action == path[:id] }.first  
else  
perm = permissions.select { |p| p.controller == path[:controller]  
&& p.action == path[:action] }.first  
end

```
return true if perm

false

```

end[/code]
