I have a resource called Book, then I have domains like:
domain.com/books/272
But I want to change it to
domain.com/stories/272
Only for the URL, don't need to change controller, classes etc.
In the routes I have
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
map.root :controller => 'static'
How can I do it? Thanks
In rails 3, I believe you would do the following:
resources :books, :path => 'stories'
Depends really on what you have already.
Use this code to your routes file: (in the case of the original URL of books replaced by stories)
#resource routes
map.resources :books, :as => :stories
#named routes
map.books 'stories/:id'
Without defining routes the only option I can think of - which seems terribly wrong - is to add a new controller which inherits from your books controller. You'd need to go through your application and change the controller name used to generate paths or URLs as seen in the following example:
class BooksController < ApplicationController
class StoriesController < BooksController
Personally, I would recommend you take the time to define your routes but I guess this depends on how large an application you're working with.
This guide will help you understand routing in RoR: http://guides.rubyonrails.org/routing.html
Its called named routes and is done in your config/routes.rb
In your routes file:
map.stories 'stories/:id', :controller => 'books', :action => 'show'
Then in your view you can access this route with:
<%= link_to book.name, stories_path(book) %>
Make sure you change book.name to whatever name you want. also make sure you passing book as a local variable to the routes path.
You can also change the :id to be more SEO friendly with to_param in the respective model.
In your model:
def to_param
"#{id}-#{name.gsub(/\s/, '_').gsub(/[^\w-]/, '').downcase}"
end
Also make sure you replace name with an attribute that the book model actually has.
Related
In rails 4.2 I have a controller that I want to fill with non resourceful routes something like
class TwilioController < ApplicationController
def add_to_queue
end
def another_action
end
end
I then want to access theese actions like so
http://appdomain/twilio/add-to-queue
and
http://appdomain.com/twilio/another-action
I realise I could do this like so in the routes file
get 'twilio/add-to-queue', to: 'twilio#add_to_queue'
get 'twilio/another-action', to: 'twilio#another_action'
but is there a way of grouping all of them together so I don't have to explicitly add twilio at the beginning of each route.
Ok I have figured out a solution, it seems quite a succinct one.
scope path: 'twilio', as: 't' do
get 'add-to-queue', to: 'twilio#add_to_queue'
end
So i now have routes like:
t_add_to_queue GET /twilio/add-to-queue(.:format) twilio#add_to_queue
Here's my solution that works in Rails 3.2.
scope :path => :twilio, :controller => :twilio, :as => :twilio do
get :add_to_queue
get :another_action
get :yet_another_action
end
:path adds \twillio\... to the URL
:controller maps all the nested routes to TwillioController
:as appends the URL helpers with twillio_....
I have a simple problem where in a routes/url name is determined by a user role. Currently the route displayed is /new_admin/dispensaries. If the user has a role of either manager or executive then the named route should be '/dashboards/dispensaries'.
It's kind of simple but the hard part is that in my routes.rb:
namespace :new_admin do
resources :vendor_templates
resources :markdown_docs
resources :email_lists
namespace :moderation do
resources :reported_reviews
end
resources :users do
member do
get :user_bans
post :ban_unban, to: 'user_bans#create'
delete :ban_unban, to: 'user_bans#destroy'
end
end
# TODO - this should be written generically to support dispensary/doctors/whatever
get '/dispensaries/reviews', :to => "reviews#all", :as => :all_reviews
get '/dispensaries/pictures', :to => "pictures#all", :as => :all_pictures
get '/dispensaries/videos', :to => "videos#all", :as => :all_videos
get "/dispensaries/autocomplete", to: "dispensaries#autocomplete"
resources :vendors do
resources :ownership_transfers, only: [:new, :create]
end
...
I'm kind of stuck since if I change the new_admin routes, so many other routes will be affected. Any idea guys?
We've actually done something like this. It's not pretty, but this solution worked for us:
Slugs
You're basically alluding to a type of your routes called Slugs. This is where you use a name instead of an ID, allowing you to make a user-friendly route (such as /delivery/today). The problem is that in order to create these routes, you have to define them individually in the routes file
There are two Gems you can use to handle your slugged routes -- FriendlyID & Slugalicious. Both of these allow you to create slugged routes, but FriendlyID basically just changes the ID, whilst Slugalicious is a totally independent system
We used Slugalicious for the code below, however, you'll probably want FriendlyID (there's a RailsCast for it here):
Routing
The problem you have is that routes are outside the scope of the RESTful controller interface, which means you'll have to call all the routes exclusive of your resources references in the routes.rb file
If you use Slugalicious, it has its own Slugs database, which means we can use it to create the routes on the fly, like this:
#Slugs
begin
Slug.all.each do |s|
begin
get "#{s.slug}" => "#{s.sluggable_type.downcase.pluralize}#show", :id => s.slug
rescue
end
end
rescue
end
This is live code, and outputs all the slugs in the routes file dynamically. The way we managed to get this to update programmatically was to use an Observer Class like this:
class SlugObserver < ActiveRecord::Observer
def after_save(slug)
Rails.application.reload_routes!
end
def after_destroy(slug)
Rails.application.reload_routes!
end
end
I appreciate you may have your answer already, but as you're a beginner, I felt I could help out by explaining the slug stuff for you
I have some problems using will_paginate and named routes.
Here is some code (my site is in Spanish language):
routes.rb
map.animals '/animales/:scope/:id', :controller => :categories, :action => :show
with these routes I generate URLs like:
www.domain.com/animales/mamiferos/perros
but, when pages links are generated I get links like:
www.domain.com/animals/perros?page=2&scope=mamiferos
Why are they like that?
NOTE: I am also using friendly_id.
You need to make sure that there is no matching route before the animals route in the routes.rb file. E.g. the default route map.connect ":controller/:action/:id" and the resource definition map.resources :animals should come after the named animals route.
I want to copy the twitter profile page and have a url with a username "http://www.my-app.com/username" and while I can manually type this into the address bar and navigate to the profile page I can't link to the custom URL.
I think the problem is in the routes - here's the code in my routes.rb
map.connect '/:username', :controller => 'users', :action => 'show'
Also, I have Question and Answer models and I want to link to them with the customized URL like so:
http://www.my-app.com/username/question/answer/2210
There's nothing wrong with your route. Just remember to define it at the end, after defining all other routes. I would also recommend using RESTful routes and only if you want to have better looking URLs use named routes. Don't use map.connect. Here's some good reading about Rails routes.
Here's how this could look:
map.resources :questions, :path_prefix => '/:username' do |question|
question.resources :answers
end
map.resources :users
map.user '/:username', :controller => 'users', :action => 'show'
Just a draft you can extend.
To create urls you need to define to_param method for your user model (read here).
class User < ActiveRecord::Base
def to_param
username
end
end
I know this questions is old but it will help someone.
You could try the below. I've used it in a rails 4 project and all seems to be working great. The reason for the as: :admin is I also had a resources posts outside of this scope. It will add a admin to the helper calls e.g. admin_posts_path
scope ":username", module: 'admin', as: :admin do
get '', to: 'profiles#show'
resources :posts
end
I have used like this
In View part
portfolio.user.name,:id =>portfolio) %>
and in rout.rb
map.show_portfolio "portfolios/:username", :action => 'show_portfolio', :controller => 'portfolios'
I'm currently following the Shovell tutorial in the Simply Rails 2 book. On page 168, it mentions URL Helpers for the Story Resource:
stories_path /stories
new_story_path /stories/new
story_path(#story) /stories/1
edit_story_path(#story) /stories/1/edit
The above is then used in the controller:
def create
#story = Story.new(params[:story])
#story.save
redirect_to stories_path
end
My routes.rb:
ActionController::Routing::Routes.draw do |map|
map.resources :stories
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
It looks like stories_path is the url name to /stories. Is that explicitly defined somewhere within my app, I can't seem to grep for that keyword. If not, is there a way that I can check the mapping above from the Rails console or somewhere else? In Django, url names are usually explicitly defined in urls.py, I just can't figure out how the above is being generated. Any documentation and pointers will help.
To get a list of the mapped routes:
rake routes
What map.resources :stories is doing is mapping your RESTful actions (index, show, edit etc.) from the stories_controller.rb to named routes that you can then use for simplicity.
routes.rb includes helpful tips on defining custom routes and it may be worth spending a little bit of time looking at resources in the API to get a better understanding:
http://api.rubyonrails.org/classes/ActionController/Resources.html#M000522
I think checking out the Rails Guides on Routing will help you a lot to understand what's going on
In short, by using the
map.resources :stories
the Router will automatically generate some useful (and RESTful) routes. Their path will take the model name (remember in Rails there is the Convention over Configuration motto), and, by default, will generate routes for all the REST actions.
This routes are available through your controller, views, etc.
If you want to check out which routes are generated from your mappings, you can use the "rake routes" command.
Now, given that, you can also write explicit URLs on your routes.rb file for actions or events that don't quite comply with the REST paradigm.
For that, you can use
map.connect "/some_kind_of_address", :controller => :pages, :action => "something_else"
Or
map.home "/home", :controller => :pages, :action => "home"
The last one will gave you both home_path and home_url routes you can use in your code.