Closed george closed 12 years ago
Here's preliminary code:
# lib/focused_controller/route_mapper.rb
def to_option
if @options[:to] && @options[:to].match(/^[\w\d]+\#[\w\d]+$/) # Handles simple case i.e. 'sessions#new'
name = ''
controller, action = @options[:to].split('#')
name << controller.camelize << 'Controller::'
name << action.camelize
name
elsif @options[:to] && !@options[:to].respond_to?(:call)
@options[:to]
# more code ...
and the tests to make it work:
it 'creates routes that map to focused controllers' do
route_set.draw do
focused_controller_routes do
match 'posts' => 'PostsController::Index'
get 'login' => 'sessions#new', as: 'login'
resources :sessions
resources :comments do
resources :replies
end
resource :account
namespace :admin do
resources :comments
end
end
end
mappings = {
[:get, '/login'] => 'SessionsController::New',
# more code...
Problem is, the test test_0002_doesn_t_mess_with_callable_routes
doesn't pass because that test uses an Object
with a dummy call
method. @jonleighton any suggestions as to how I should handle the failing test case?
Well 'sessions#new' doesn't response to #call
so you could put another conditional under what is now the first branch I think.
Have you looked into re-using the existing code in Rails that matches e.g. sessions#new? Ideally we would hook into that, but this part of rails is quite a mess so it may not be possible.
Good idea. I had a hunch Rails might have done that already but didn't venture to look. Let me see what I find in Rails.
OK, I found the line in the ActionDispatch library here that has the functionality I'm looking for. I'll take another stab at the code with this in mind.
I'd like to call the private method default_controller_and_action
in ActionDispatch::Routing::Mapper
from my preliminary code above, but that sounds like code blasphemy. @jonleighton looks like I would have to clean up the Mapper class to tackle the present issue. Who would you recommend I send Rails patches for review? I've submitting unaccepted/ignored patches in the past to the rails repo. Now I understand it is better if someone reviews them beforehand; it is more likely they'll get accepted.
The entire of ActionDispatch::Routing::Mapper
needs to be refactored really... but either way we still need to support old versions of Rails in Focused Controller. So tbh I would just use send
to call the private method - we're already monkey patching anyway.
Could one of you please explain the option[:to]
here?
I've been looking at the docs for #url_for
at http://apidock.com/rails/ActionDispatch/Routing/UrlFor/url_for to try to get a clue, but nothing there that I see...
I'm trying to get this to work:
def wizard_path(goto_step = nil, options = {})
options = {
:controller => wicked_controller,
:action => 'show',
:id => goto_step || params[:id],
:only_path => true
}.merge options
# options = FocusedController::RouteMapper.new(options, options).options
puts "url to: #{options}"
url_for(options)
end
If I leave out the use of the RouteMapper
which adds the :to
option, I get:
ActionController::RoutingError: No route matches {:controller=>"JumpController", :action=>"show", :id=>:last_step}
module JumpController
class Show < Action
def run
# ...
end
end
end
What's the secret here?
The
focused_controller_routes
helper appears to not support theas: 'named_route'
construct:rake routes
:@jonleighton provided a workaround on the mailing list, which works well:
If I can make some time, I'll take a crack at a patch. I took a cursory look at it, but I don't yet understand how it's all working. Any direction someone could provide would be most welcomed.