How to change a route name rails 4 - ruby-on-rails

I changed the routing of posts#index to match blog and I now get /blog in the URL which I was trying to accomplish.
I've tried several different things to get my actual blog post which the route currently looks something like /posts/this-is-a-test to also use blog rather than posts in the URL.
Below is my current route file. I am using the friendly_id gem, if that makes any difference in answering this question.
resources :posts do
resources :comments
end
resources :contacts, only: [:new, :create]
root "pages#home"
get "/home", to: "pages#home", as: "home"
get "about" => 'pages#about'
get "pricing" => 'pages#pricing'
get "contact_us" => 'pages#contact_us'
match 'blog', to: 'posts#index', via: :all
end

path option along with resource must help.
resources :posts, :path => 'blogs' do
resources :comments
end
This will change all /posts and /post to /blogs/ and /blog.
If you want to change your route's helper methods such as posts_path to blogs_path and new_post_path to new_blog_path etc, you can change it with as tag.
resources :posts, :path => 'blogs', :as => 'blogs' do
resources :comments
end
Or yet better, you can specify the controller and route blogs directly as:
resources :blogs, controller: 'posts' do
resources :comments
end
This is the awesomeness of Rails! :)

match 'blog/:id' => 'posts#show'
should work. But if you want to match every method in posts controller to blog (and you don't want to use the posts path), I would just rename the controller to blog instead and add resource :blog in the routes.

This helped me, from official guides documentation, add this in your routes.rb file:
get '/patients/:id', to: 'patients#show', as: 'patient'

Related

The action x could not be found for xyzController

I'm a beginner in Ruby on Rails and I have a problem. I'm trying to add comments to my app. Everything is working, but when I added this code to routes.rb
resources :galleries do
resources :comments, module: :galleries
end
resources :articles do
resources :comments, module: :articles
end
I can't update any gallery or article. My whole routes.rb:
Rails.application.routes.draw do
devise_for :users
resources :galleries do
resources :comments, module: :galleries
end
resources :articles do
resources :comments, module: :articles
end
match ':controller(/:action(/:id))(.:format)', via: [:post, :get]
root 'public#index'
end
It looks like the request (articles/12?page_id=4) is falling through to the match statement and not getting picked up by your resources. Your match statement:
match ':controller(/:action(/:id))(.:format)', via: [:post, :get]
is matching "articles" as the controller, and looking for "12" as the action and it clearly can't find it.
I would scrap the match statement and go strictly with named routes or resourceful routing permanently, or at least while debugging. Next, run
rake routes
and check the results. From your routes.rb I am guessing you will have a line like this:
article GET /articles/:id(.:format) articles#show
If that is indeed the case, make sure you have the show() method defined in the articles controller, and verify that the logs are showing a GET request for it.

Two routes with multiple parameters to single controller's method?

Let's assume I have models: Article, Post, and Comment. For these models I need to map CommentsController#show in articles and posts. Something like this:
resources :articles do
resources :comments, :only => [:show]
end
resources :posts do
resources :comments, :only => [:show]
end
And this works perfectly, i.e. it'll generate routes something like this:
/articles/:article_id/comments/:id
/posts/:post_id/comments/:id
Both pointing to the same controller's single method: CommentsController#show
What I need is to include more/multiple parameters for posts while retaining the same URL routes to CommentsController:
/articles/:article_id/comments/:id
/posts/:post_id/:post_title/:post_year/comments/:id
I tried match but first occurrence at resources :articles do... overrides it.
resources :articles do
resources :comments, :only => [:show]
end
match '/posts/:post_id/:post_title/:post_year/comments/:id', :to => 'comments#show', :as => :show_post_comments
It throws an error:
No route matches {:controller=>"comments", :action=>"show",
:post_id=>10, :post_title=>"some title", :post_year=>"1995", :id=>"1"}
So, is it possible to create such a route with multiple parameters to single controller's method in two resources using get or something?

Trouble with routing for my semi-static pages

I'm trying to implement semi-static pages as per this railscast
At first I named my class 'About', but that threw the following error:
Invalid route name, already in use: 'page' (ArgumentError)
You may have defined two routes with the same name using the :as option, or you may be overriding a route already defined by a resource with the same naming.
After some googleing, it seemed like it was conflicted with active_admin for some reason, so I rename the table to 'Page' and I've carefully renamed all the appropriate files, classes and methods etc. from 'About' to 'Page'
This is my Page model:
class Page < ActiveRecord::Base
validates_uniqueness_of :url
def to_param
url
end
end
And these are my routes:
get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
resources :users
resources :sessions
resources :password_resets
resources :posts do
resources :comments
resources :votes, only: [:new, :create]
resources :flags, only: [:new, :create]
end
resources :comments do
resources :comments
resources :votes, only: [:new, :create]
resources :flags, only: [:new, :create]
end
resources :newsletters
resources :pages, except: :show
resources :subscribers, only: [:index, :new, :create]
# resources :prelaunch
# get 'about', to: 'prelaunch#about'
root to: 'posts#index'
get ':id', to: 'pages#show', as: :page
I'm still getting the same error as described above.
The only way I can get it to half-work is by dropping the 'as: :page' bit, which stops the conflict, and hardcoding the url I want to point to into the code e.g.
<%= link_to page.name, "localhost:3000/#{page.url}" %>
which is far from ideal.
I can't find any help in Routing from the Outside In.
Could anyone help?
Here's the fix:
#config/routes.rb
resources :pages, except: :show
(remove get ':id', to: 'pages#show', as: :page)
This will create the standard RESTful routes, which will create a routing structure except the show action
Slugs
How to create app-wide slug routing for Rails app?
If you want to have /about etc, you'll have to generate them specifically:
#config/routes.rb
if Page.all.any?
Page.all.each do |page|
get page, to: "pages#show", id: page.id
end
end
This can also be handled with friendly_id
Have you considered using a gem that "does the work for you"? I've been using the https://github.com/thoughtbot/high_voltage gem to take care of static pages for me, without any hassle. It takes care of both routing and controller, only leaving the creation of the pages in a dedicated view/pages folder. Linking to a static page is as simple as creating a link to page_path(:name_of_the_page)
Ok, after a lot of hacking around and a helpful pointer from Rich Peck, I've got a working solution.
Routes:
resources :pages, except: :show
if Page.all.any?
Page.all.each do |page|
get "#{page.url}", to: "pages#show", as: "#{page.url}", id: page.id
end
end
Controller:
def show
#page = Page.find(params[:id])
end
Note, I've used the friendly_id gem as suggested.
To dynamically generate links:
Application controller:
def about_us
#pages = Page.all
end
helper_method :about_us
Pages helper:
def about_link(page)
link_to page.name, "/#{page.url}"
end
NB: - you need to include the / otherwise it will try to prepend the name of the controller for the page you're on (I'm not sure why).
My footer:
<% about_us.each do | page | %>
<%= about_link(page) %>
<% end %>
UPDATE:
I've had a lot of trouble deploying my app to Heroku, and I believe it's because of the pages routes.
I've now changed to a much simpler solution:
resources :pages, path: ""
and the problem's have gone away.

Rails 4: Simple Custom route redirecting to show action

I'm very new to rails and I'm having trouble with routes. I'm trying to link between views in two different controllers.
In clients#index
<li><%= link_to "Manage Client Payments", payments_per_client_path %></li>
In Payments Controller:
def payments_per_client
#payment = Payment.all
end
In routes file:
resources :payments
resources :direct_debits
resources :clients do
resources :payments
end
controller :payments do
get 'payments/payments_per_client' => 'payments#payments_per_client', :as => :payments_per_client
end
The problem is that url for 'Manage Client Payments' displays in my browser as:
/payments/payments_per_client
but the link redirects to payments#show. I have no idea why this is happening.
Just change the route path as follows and remove controller block
match 'payments/payments_per_client' => 'payments#payments_per_client', :as => :payments_per_client
u need to reorder your routes
controller :payments do
get 'payments/payments_per_client' => 'payments#payments_per_client', :as => :payments_per_client
end
resources :payments
resources :direct_debits
resources :clients do
resources :payments
end
becoz your resouces :payments already have a routes /payments/:id which is the routes for your payments show page that's why payments_per_client is treated as an id and it redirects you to show page.
You can use this:
get 'payments/payments_per_client', to: 'payments#payments_per_client', as: :payments_per_client
or
match 'payments/payments_per_client' => 'payments#payments_per_client', as: :payments_per_client
or
match 'payments/payments_per_client' => 'payments#payments_per_client', as: :payments_per_client, via: :get

Exposing a Specific Action of a Nested Route

Using this as an example contexted:
Post has_many comments
Comment belongs_to post
I have a route that looks like:
resources :posts do
resources :comments
end
How do i create a route that exposes comments#index?
An example use case would be... I want to list ALL comments in the system on a page. Essentially using the comments resource as if it's not nested when a user hits /comments
thank you!
Try this.
resources :posts do
resources :comments, :except => :index
end
match 'comments' => 'comments#index', :as => :comments
That said, I usually look to avoid routes like this because I like a tidy RESTful routes file, but sometimes it can't be helped.
Second option:
resources :posts do
resources :comments, :except => :index
get :comments, :on => :collection
end
In the second option, you'd want to remove the index action from the comments controller and create a comments action in your posts controller.

Resources