Laravel routes with not specified number of arguments - laravel-5.1

I created website where site admin can create new taxonomy terms, rearange them and hierarchize at his will. My question is therefore this: Is there any way, how to handle route with not specified number of arguments?
I am strongly against manual solutions like this:
Route::get('/{term1?}/{term2?}/{term3?}/{term4?}/{term5?}', "controler#handle");

Related

Generating the URL of a nested resource without its parent (without using shallow)

In our application, many resources are nested under a common resource representing an organization. Most URLs include an organization ID the following pattern: /:organization_id/notifications/:id.
My problem is that I always have to give the current organization to generate the URL to any model. For example, the link to an existing notification would be link_to [#organization, #notification].
Since a notification already belongs to an organization, I was wondering if it was possible to generate my URL using link_to #notification and it would actually generate a URL including the organization ID of the notification. I was hoping that a configuration in the model would be able to achieve this but I could not find anything in the guides, the docs or the source code of Rails.
I would like to keep the organization ID visible in the URL as this is an information that is used by our customers. So I do not want to use shallow nested resources for this problem.
We are using Rails 5.2.0.
You want the resolve route definition method.
It is designed to do exactly what you want: configure a different behaviour when a single model instance is passed to url_for (as link_to does, for example).
Specifically, in your config/routes.rb, something like:
resolve("Notification") do |note|
[:notification_organization, note.organization, note]
end
It sounds like you were on the right track -- it's just a routing concern rather than a model one.

Ruby on Rails - Routing - Appropriate situations to use a namespace over a scope?

In my application I have a few navigation items that are dropdown menus. The only constraint I have is that each link in a dropdown menu should have its url path prefixed with the menu name that it belong to. For example:
http://example.com/dropdown1/page1
http://example.com/dropdown1/page2
http://example.com/dropdown1/page3
http://example.com/dropdown2/page4
http://example.com/dropdown3/page5
http://example.com/dropdown3/page6
I understand that I have two options when creating the routes for these pages.
Use a scope. Only the url path is scoped / prefixed.
Use a namespace. In addition to the url being scoped / prefixed, the controllers, views, models, and path helpers will be namespaced as well.
The pages in each dropdown house different independent features, but each feature in the dropdown shares the same category. Does it make more sense to namespace these features or to just scope them?
If your only constraint is that each link in a dropdown menu must have its url path prefixed with the menu name that it belongs to, then my suggestion is to just scope the routes for those dropdown paths.
Namespacing provides a greater degree of separation out of the box, and is more useful for scenarios like having an admin section, or an API layer, where the same resources would behave differently depending on their namespace.
Scoping gives you a bit more control, allowing you to specify what should be namespaced - in this case if only the routes are different, then you can have something like:
scope 'dropdown1' do
# routing here
end
The Rails guides does a good job explaining the usage of namespacing:
Most commonly, you might group a number of administrative controllers under an Admin:: namespace. You would place these controllers under the app/controllers/admin directory, and you can group them together in your router.

User defined routes in Rails

There is a lot of good information on routing in Rails. I must be missing something, but I can't seem to find a good example of a Rails application that allows dynamically defined user specific routes.
For example, my application is hosted at:
www.thing.com
... and serves out user generated content.
I'd like to give the user an option to define a suffix that let's them share a somewhat customized URL to their content. For example, if a user 'joe' generates some car info they might want to make it avilable via joescars at:
www.thing.com/joescars
Maybe later they decide they want to serve it out under 'carsbyjoe' at:
www.thing.com/carsbyjoe
I can handle limiting what suffixs are valid. Is there a Rails way to codify this kind of dynamic routing?
There is a way to do this. In your config/routes file add a route that says get '/:user_route' => 'somecontroller#someaction'. You'll have to put it at the very bottom because routes are matched from top to bottom and this will match things like /users or other routes you'll likely want directed elsewhere.
Then, in your controller you can access params[:user_route] to show the appropriate content. There are a number of ways to store this custom content in your database, depending on your needs. You might have a model representing these custom routes like CustomRoute.find_by_route(params[:user_route]), or maybe each user will have a custom route so you could do User.find_by_route(params[:user_route]).custom_page and each User has one custom_page.

Ruby on Rails database driven router to support fully customizable urls

I'm planning to port our current cms (written in PHP) to Rails. All parts do well, except for one: routing.
Like most cms systems, the routing in our cms based on a database with pages, which are linked to modules, controllers and actions. On this approach a user can fully customize or specify it's own urls.
I know that Rails (and most (application) frameworks have the approach of defining routes in a file, but I hope this is possible.
The approach our users should have is:
add new page
select type (news, form, product, ...)
select an item (select which form, blog or product should be displayed)
enter a url for that page
Special the last point (4) is important. A user should be able to add form A to /contact-us, and form B to /clients/register-as-new-client e.g.
On a request the router needs to do a database query with the page url, to find out which controller, task and parameters should be dispatched.
Question has been updated, and i don't think this is a valid answer anymore
we have a similar paging system. we use a routing glob. in routes.rb:
get 'pages/*lookup_path', to: 'pages#show', defaults: { format: 'html' }, as: 'page'
Just parse params[:lookup_path] in PagesController to suit your needs
'http://localhost/pages/users/'
params[:lookup_path] #=> users/
'http://localhost/pages/users/23'
params[:lookup_path] #=> users/23
'http://localhost/pages/people/1'
params[:lookup_path] #=> people/1
Although this solution isn't ReSTful, I think this should solve the issue.
Regardless, Rails uses routes in a file. You cannot change this since the framework heralds "convention over configiuration". All I can do is point you in a direction to minimize this.
There is a catchall route in Rails (on RailsCasts, and on StackOverflow) which you can use to direct all routing to one controller action. You may further customize the routing behaviour in that method
You could also make a route like…
:controller/:action => Controller::Action
…as is done in CodeIgniter, but now your methods have to have names like contact-us and register-as-a-new-client.

Friendly URLs in Github

How has Github managed to get friendly URLs for representing repos of users? For a project called abc by username foo, how do they work around with a URL like: http://github.com/foo/abc. Are they fetching the abc model for the DB from the title in the URL (which sounds unreasonable as they are modifying the titles). How are they transferring the unique ID of the abc repo which they can fetch and show in the view?
The reason I ask is that I am facing a similar problem of creating friendlier URLs to view a resource. MongoDB's object IDs are quite long and make the URL look horrific. Is there a workaround? All the tutorials that demonstrate CRUD (or REST) URLs for a resource always include the object's unique ID(e.g. http://mysite.org/post/1 or http://mysite.org/post/1/edit. Is there a better way to do it?
Not having seen their code, I couldn't tell you exactly how they do it, but if you're using Rails there are at least two Ruby gems that will give you similar results:
Take a look at Slugged and friendly_id
http://github.com/foo/abc is a unique repository identifier (for that repo's master branch). I'd assume that somewhere they have a table that looks like:
repository-id | user-id | project-id
and are just looking up based on user and project rather than repository-id.
You'd need to do some domain-specific mapping between internal and user-friendly ids, but you'd need to make sure that was a 1:1 mapping.
See this rails cast on methods, gems and solutions to common problems you might get while modifying the application to use friendly urls.
http://railscasts.com/episodes/314-pretty-urls-with-friendlyid?view=asciicast
(although Ryan Bates deserves the rep+ for this)
I mocked a structure like this using FriendlyID and Nested Resources.
Essentially, use friendly ID to get the to_param-ish slugs in your routes, then set up nested resources. Using GitHub as an example:
routes.rb
resources :users do
resources :repositories
end
Then in your controller, say, for repositories, you can check the existence of params[:user_id] and use that to determine the user from the route. The reason I check for existence is because I did something like (roughly):
/myrepositories/:repository_id
/:user_id/:repository_id
So my controller does:
def show
#user = params[:user_id] ? User.find(params[:user_id]) : current_user
end
I followed this tutorial here to get started with this same project.
This is called URL rewriting if the web server does it (such as Apache), and routing when it happens in a web application framework (such as Ruby on Rails).
http://www.sinatrarb.com/intro#Routes
http://httpd.apache.org/docs/current/mod/mod_rewrite.html

Resources