Open jaysneg opened 6 years ago
Hi @jaysneg Thank you for open this issue!
I think amber already support resources
. Perhaps we just need to add more capabilities to it,
@amberframework/contributors WDYT?
I agree, this will be a good feature to have. Here is my current workaround. I have a file at src/controllers/application/url_helpers.cr
which is included into my application_controller and has code like this:
module UrlHelpers
def root_path
if current_user.guest? || ! current_user.activated?
"/"
else
domains_path
end
end
def users_path
"/users"
end
def user_path(user : User)
"/user/#{user.id}"
end
def new_user_path
"/me/register"
end
def invited_user_registration_path(invite : Invite)
"/me/register?invite=#{invite.code}"
end
def user_activation_path
"/me/activate"
end
# on and on for 150 lines
end
I think this is a great Idea.
Some ideas for this would be to include action type check support so for instance if the action does not exist then it throws an error similar to the way Lucky does it.
This basically can introspect the controller action methods to generate the helpers dynamically. And maybe instead of creating methods for it we can create something more intuitive User::New.with(:id)
For each controller define in routes we can dynamically generate helpers as
# Routes
post "/users/activation/:id#integer", UsersController, :activation
# Generated helper
Users::Activation.path(user_id: interger)
@eliasjpr If we generate routes based on controller and action, and not based on the actual path, we will never be able to have a single action be accessible at two different paths.
@eliasjpr @shobhitic generating the named routes based off of controller and action seems like a fine way to provide a default. As long as there as a way to override the default, I'm in favor. Rails does this surprisingly well with some very simple method declarations.
@robacarp IMO, it's not the best default. Lots of times while refactoring, you tend to move an action from one controller to the other while keeping the path to access it same. Happens all the time while refactoring APIs because you can't change routes there. In situations like these, you'll have to change all the references to path, unlike in Rails where the path method is based on the path being used, and not how it's implemented.
I think we should also create path methods based on paths, and not based on their implementations.
@robacarp I would suggest the above example as a start point, I believe if you want to define a custom path that should be more of a global path helper method.
I am also fine with the way Rails does this, but having some checks at compile time would be very beneficial this would avoid having dead URL paths in a large app.
I'm not sure this is something that can be generalized and implemented at the framework level. But the docs could add some implementation suggestions or the generator could create a helper, perhaps.
In the spirit of providing more ideas/working code examples, here's what I do:
macro resource_paths(klass, plural, to_param_method = :id)
{% singular = klass.id.underscore %}
def {{plural.id}}_path
"/{{plural.id}}"
end
def new_{{singular.id}}_path(**params)
qs = params.map { |k, v| "#{URI.escape(k.to_s)}=#{URI.escape(v.to_s)}" }.join("&")
"/{{plural.id}}/new" + (qs.blank? ? "" : "?#{qs}")
end
def {{singular.id}}_path({{singular.id}} : {{klass.id}})
"/{{plural.id}}/#{{{singular.id}}.{{to_param_method.id}}}"
end
def edit_{{singular.id}}_path({{singular.id}} : {{klass.id}})
"/{{plural.id}}/#{{{singular.id}}.{{to_param_method.id}}}/edit"
end
def link_to(body : String, obj : {{klass.id}}, **options)
link_to(body, {{singular.id}}_path(obj), **options)
end
def link_to(body : String, obj : {{klass.id}}, **options, &block)
link_to(body, {{singular.id}}_path(obj), **options, &block)
end
def redirect_to(obj : {{klass.id}}, **args)
redirect_to({{singular.id}}_path(obj), **args)
end
end
resource_paths User, :users
@eliasjpr It gets a 99 on Desktop and 93 on Mobile, that's way better than most websites get. Is this a priority for Amber still?
Would love to see the the resources
macro generate path
and url
helpers. Anyone interested in taking this on?
I use this code I wrote on my case to generate the routes.
This might not the cleanest way to do it but it works, to use it:
crystal generate_routes.cr
, it will create a view_path.cr
helper you can include with all the paths
Description
Add automatically create paths and URL Helpers like at Rails
Steps to Reproduce
http://guides.rubyonrails.org/routing.html#path-and-url-helpers
Versions
0.7.2