Skip to content

Instantly share code, notes, and snippets.

@iHiD
Created June 6, 2012 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iHiD/2882545 to your computer and use it in GitHub Desktop.
Save iHiD/2882545 to your computer and use it in GitHub Desktop.
Basic CS -> Rails routes converter.
require 'rails/application/route_inspector'
class Journey::Visitors::Formatter
def visit_SYMBOL node
key = node.to_sym
if value = options[key]
consumed[key] = value
value # Overritten this line to avoid escaping of characters
else
"\0"
end
end
end
class CoffeeScriptRouteParser
def self.parse(name, *unnamed_params)
# Split params for product_option_path(:product_id, :id, {format: 'json', anchor: 'foobar'})
# into [:product_id, :id], and {format...}
named_params = unnamed_params.last.is_a?(Hash) ? unnamed_params.pop : {}
name.gsub!(/_path$/, '')
name.gsub!(/_url$/, '')
# Get the relevant route.
route = Rails.application.routes.routes.select {|route| route.name == name }.first()
# Convert parts into a hash
parts = {}
# Override any named params
named_params.each do |k,v|
parts[k] = '#{' + v + '}'
end
# And any unnamed params
unnamed_params.each_with_index do |param, index|
parts[route.parts[index]] = '#{' + param + '}'
end
# Now use the overriden formatter to create the URL.
route.format(parts)
end
end
RailsCoffeescriptRoutes::Application.routes.draw do
resources :products do
resources :options
end
match 'products/:id' => 'catalog#view', as: :catalog
match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
match ':controller(/:action(/:id))(.:format)', as: :lots_of_options
end
require 'test_helper'
class RoutingTest < ActiveSupport::TestCase
test "truth" do
assert_kind_of Module, RailsCoffeescriptRoutes
Rails.application.routes.routes.each{|route|p route.name if route.name}
end
####
#
# This sits as part of coffee-rails
# It adds a list of reserved methods to CoffeeScript with the names of the routes.
# When CS hits a reserved method name, it then backs it off to a function such as CoffeeScriptRouteParser.parse
# which takes the method name and the arguments. I'm presuming coffeescript is tokenising the code.
# If not, then we'll need more work to get it out of CS.
#
# It then simply uses the Rails routing internals to get the proper URL to call.
#
# This currently outputs as coffeescript using #{} for string concatenation.
# It might be better to use Javasacript to do it, but I know very little about the CS compiler.
#----
test "resources paths" do
# products_path
assert_equal '/products', CoffeeScriptRouteParser.parse('products_path')
# products_path(format: 'json')
assert_equal '/products.#{"json"}', CoffeeScriptRouteParser.parse('products_path', format: '"json"')
# product_path(1)
assert_equal '/products/#{"1"}', CoffeeScriptRouteParser.parse('product_path', '"1"')
# product_path(1, format: json)
assert_equal '/products/#{"1"}.#{"json"}', CoffeeScriptRouteParser.parse('product_path', '"1"', format: '"json"')
assert_equal '/products/new', CoffeeScriptRouteParser.parse('new_product_path')
assert_equal '/products/edit', CoffeeScriptRouteParser.parse('edit_product_path')
end
test "nested resources paths" do
assert_equal '/products/#{product_id}/options/#{option_id}', CoffeeScriptRouteParser.parse('product_option_path', 'product_id', 'option_id')
end
test "manual paths" do
assert_equal '/products/#{some_var}', CoffeeScriptRouteParser.parse('catalog_path', "some_var")
assert_equal '/products/#{some_var}/purchase', CoffeeScriptRouteParser.parse('purchase_path', "some_var")
end
test "lots of options" do
assert_equal '', CoffeeScriptRouteParser.parse('lots_of_options')
assert_equal '/#{controller_var}', CoffeeScriptRouteParser.parse('lots_of_options', controller: 'controller_var')
end
end
@iHiD
Copy link
Author

iHiD commented Jun 6, 2012

There's a repository with these files in at https://github.com/ihid/rails-coffeescript-routes - if you want to send pull-requests there with failing tests, then I will get them passing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment