Ruby on Rails: /articles/:id not matching /articles/1 - ruby-on-rails

I'm brand new to Ruby on Rails, and am working through the tutorial http://edgeguides.rubyonrails.org/getting_started.html
I started by setting up an 'articles' route, and have the following routes when running 'rake routes':
'article GET /articles/:id (.:format) articles#show'
So, I see that there is a path, /articles/:id, which should map to articles#show. however, when I hit the url: /articles/1, I get the following error:
"Unknown action
the action '1' could not be found in the ArticlesController"
I'm just not at all sure whats happening here. Show is defined in my articles_controller.rb:
class ArticlesController < ApplicationController
def new
end
def create
#article = Article.new(params[:article])
#article.save
redirect_to #article
end
def show
#article = Article.find(params[:id])
end
def index
#articles = Article.all
end
private
def article_params
params.require(:article).permit(:title,:text)
end
end
anyone have ideas?
Update: added Routes.rb
RailsStarter::Application.routes.draw do
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
get ':controller(/:action(/:id))'
root :to => 'say#hello'
# Sample resource route (maps HTTP verbs to controller actions automatically):
resources :articles
end

Remove the get ':controller(/:action(/:id))' from the routes.rb file
You should probably remove (or update) the root route as well, as say#hello is from the intro lesson.

Related

unknown action in controller - routes.rb issue? weird results by changing from singular to plural?

I'm getting a strange reaction to my 'destroy' method. I get this error when trying to destroy a project:
Unknown action
The action '5' could not be found for ProjectsController
I figured out when when I change my routes.rb file from resources :projects (plural) to resources :project (singular), the destroy action works as it should (and returns to the index) but then my show method works but update and new methods throw undefined methodprojects_path'` errors. Why is this happening??
class ProjectsController < ApplicationController
def index
#projects = Project.sorted
end
def show
#project = Project.find(params[:id])
end
def new
#project = Project.new
#project_count = Project.count + 1
end
def create
# Instantiate a new object using form parameters
#project = Project.new(project_params)
# Save the object
if #project.save
# If save succeeds, redirect to the index action
flash[:notice] = "Project created successfully."
redirect_to(:action => 'index')
else
# If save fails, redisplay the form so user can fix problems
#project_count = Project.count + 1
render('new')
end
end
def edit
#project = Project.find(params[:id])
#project_count = Project.count
end
def update
#project = Project.find(params[:id])
if #project.update_attributes(project_params)
flash[:notice] = "Project updated successfully."
redirect_to(:action => 'show', :id => #project.id)
else
#project_count = Project.count
render('edit')
end
end
def delete
#project = Project.find(params[:id])
end
def destroy
project = Project.find(params[:id])
project.destroy
flash[:notice] = "Project '#{project.name}' destroyed successfully."
redirect_to(:action => 'index')
end
private
def project_params
params.require(:project).permit(:name, :financing, :visible, :position)
end
end
routes.rb file:
Rails.application.routes.draw do
root :to => 'projects#index'
resources :projects
match ':controller(/:action(/:id))', :via => [:get, :post]
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Exampl
e resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end
Delete.html.erb page:
<% #page_title = "Delete Project" %>
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="project destroy">
<h2>Delete Projects</h2>
<%= form_for(:project, :url => {:action => 'destroy', :id => #project.id}) do |f| %>
<p>Are you sure you want to permanently delete this project?</p>
<p class="reference-name"><%= #project.name %></p>
<div class="form-buttons">
<%= submit_tag("Delete Project") %>
</div>
<% end %>
</div>
[UPDATE]
Another interesting update. I messed around with destroy and changed the controller to:
def delete
#project = Project.find(params[:id])
#project.destroy
end
def destroy
project = Project.find(params[:id])
project.destroy
flash[:notice] = "Project '#{project.name}' destroyed successfully."
redirect_to(:action => 'index')
end
I did this to see if it was an issue with the destroy method. It does destroy the project, and still returns the delete page which causes the same error, but it does destroy it.
Though you are doing a couple of unconventional stuff like having delete.html.erb (objects are deleted from the show view page), I'm going to address your direct question.
you said:
"when I change my routes.rb file from resources :projects (plural) to resources :project (singular), the destroy action works as it should (and returns to the index) but then my show method works but update and new methods throw undefined method projects_path'` errors. Why is this happening??"
you have understand every time you change your routes, you have to modify the helper paths in your views.
example: when you had resources :projects, you helper methods were (run rake db:migrate)
projects_path GET /projects(.:format) projects#index
POST /projects(.:format) projects#create
new_project_path GET /projects/new(.:format) projects#new
edit_project_path GET /projects/:id/edit(.:format) projects#edit
project_path GET /projects/:id(.:format) projects#show
PATCH /projects/:id(.:format) projects#update
PUT /projects/:id(.:format) projects#update
DELETE /projects/:id(.:format) projects#destroy
So at this point, projects_path was working because as you can see above, projects_path is there.
when you changed your routes to resources :project(singular), your helper paths change as well. run rake db:migrate to see them:
project_index_path GET /project(.:format) project#index
POST /project(.:format) project#create
GET /project/new(.:format) project#new
GET /project/:id/edit(.:format) project#edit
GET /project/:id(.:format) project#show
PATCH /project/:id(.:format) project#update
PUT /project/:id(.:format) project#update
DELETE /project/:id(.:format) project#destroy
As you can see the helper path that maps to project#index is project_index_path.
So I'm guessing in your edit.html.erb (or somewhere else) you have the old code: projects_path and so you are getting undefined method projects_path because the helper no longer exist. The correct helper method in this case, is project_index_path.

Ruby cannot route to site

I try to list all doctors in my project using <%= link_to 'Registration to visit', doctors_index51_path %> but I get error: Couldn't find Doctor with id=index51
I have added get "doctors/index51" to routes and I have something like this in doctors_controller:
def index51
#doctors = Doctor.all
respond_to do |format|
format.html # index51.html.erb
format.json { render json: #doctors }
end
end
Routes.rb:
ZOZ::Application.routes.draw do
resources :refferals
resources :clinics
resources :doctors
get "welcome/index2"
get "welcome/index"
get "patients/select51"
get "patients/show51"
get "refferals/new"
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
resources :patients
resources :doctors do
collection do
get 'index51'
end
end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
root :to => 'welcome#index'
# See how all your routes lay out with "rake routes"
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id))(.:format)'
end
Help me please, I am new in Ruby and I'm fighting with my project to school :)
In rake routes output I have:
index51_doctors GET /doctors/index51 (.:format) doctors#index51
Error:
ActiveRecord::RecordNotFound in DoctorsController#show
Couldn't find Doctor with id=index51
Rails.root: D:/Studia/Bazy Danych/Projekt/Implementacja/ZOZ
Application Trace | Framework Trace | Full Trace
app/controllers/doctors_controller.rb:25:in `show'
Request
Parameters:
{"id"=>"index51"}
probably this is what you need.
resources :doctors do
collection do
get 'index51'
end
end
edit: (after routes.rb was posted)
comment 4th statement
#resources :doctors
Its defined twice, isn't it?
This is the easiest way to achieve what your want!
get "doctors/index51", to: "doctors#index51"
and what you have done is usually works in static pages!
Hope to help!
Just looked at your routes file and noticed you are using routes like get "patients/select51"
and get "patients/show51"
What these routes do? select patient with id 51 and show patient with id 51? You are not making rails RESTful routes. You should look into rails documentation to get a better idea of what exactly is going on
Error: Couldn't find Doctor with id=index51 states that rails is looking at index51 as an id.
Fix:
You have resources :doctors inside your routes.rb file which creates seven different routes in your application, all mapping to the doctors controller like:
GET /doctors doctors#index display a list of all doctors
GET /doctors/new doctors#new return an HTML form for creating a new doctor
POST /doctors doctors#create create a new doctor
GET /doctors/:id doctors#show display a specific doctor
GET /doctors/:id/edit doctors#edit return an HTML form for editing a doctor
PATCH/PUT /doctors/:id doctors#update update a specific doctor
DELETE /photos/:id doctors#destroy delete a specific doctor
and below that you have:
resources :doctors do
collection do
get 'index51'
end
end
which is creating a get /doctors/index51 doctors#index51 and conflicting so you need to remove the earlier one. Although i'll still suggest sticking with the defaults but that will require you to make an action index rather than index51

Rails Custom Route Gets Confused on :id

I am trying to setup a custom route. However whenever I hit the beverage_locations/new page, it tries to send 'new' in the url as the :location_id in the index path.
route.rb
controller 'beverage_locations' do
get 'beverage_locations/:location_id' => 'beverage_locations#index'
get 'beverage_locations/new' => 'beverage_locations#new'
end
error
ActiveRecord::RecordNotFound in BeverageLocationsController#index
Couldn't find Location with id=new
any idea how to fix this?
Thanks!
Rails routes are matched in the order they are specified, so if you
have a resources :photos above a get 'photos/poll' the show action’s
route for the resources line will be matched before the get line. To
fix this, move the get line above the resources line so that it is
matched first.
From http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
A demo:
# beverage_locations_controller.rb
class BeverageLocationsController < ApplicationController
def index
render :text => params[:location_id]
end
def new
render :text => 'New method'
end
end
# config/routes.rb
Forfun::Application.routes.draw do
controller 'beverage_locations' do
get 'beverage_locations/new' => 'beverage_locations#new'
get 'beverage_locations/:location_id' => 'beverage_locations#index'
end
end
# http://localhost:3000/beverage_locations/1234 => 1234
# http://localhost:3000/beverage_locations/new => New method
You need to swap the order of the routes so that the new action has preference:
controller 'beverage_locations' do
get 'beverage_locations/new' => 'beverage_locations#new'
get 'beverage_locations/:location_id' => 'beverage_locations#index'
end

Get routes from database in Rails

How to load routes from database?
I have table Post with column :url. There is part of the url in this column, e.g.:
about
progs/us
progs/us/info
empty
etc.
How to set routes for this? Result example:
http://mysite.com/progs/us for the page http://mysite/posts/2
You can intercept any url by this route:
# routes.rb
get '*url' => 'posts#show', format: false
Note: this route should be declared last in your config
And controller looks like following:
# posts_controller.rb
class PostsController < ApplicationController
def show
#post = Post.find_by_url!(params[:url])
# by default "show" view is rendered with "post" variable
end
end
Here's how I made routes like this
www.example.com/jenny250
www.example.com/bob1985
At end of routes.rb
get ':username' => 'users#show'
In the users controller
def show
#user = User.find_by_username(params[:username])
# ...
end

How do I add a route which maps to a slug url generated by the stringex gem in ruby on rails 3.1?

It seems simple, in my model I have:
class CustomerAccount < ActiveRecord::Base
acts_as_url :name
def to_param
url # or whatever you set :url_attribute to
end
end
And in my controller, I have:
class CustomerAccountsController < ApplicationController
def show # dashboard for account, set as current account
#account = CustomerAccount.find_by_url params[:id]
no_permission_redirect if !#account.has_valid_user?(current_user)
set_current_account(#account)
#latest_contacts = Contact.latest_contacts(current_account)
end
end
What's currently in the routes.rb is:
resources :customer_accounts, :path => :customer_accounts.url do
member do
get 'disabled'
post 'update_billing'
end
end
That gives me the following error when I try to generate data via rake db:seed, or at least I assume the entry in routes is what's doing it.
undefined method `url' for :customer_accounts:Symbol
So what do I need to do to get the route set up? What I'd like is http://0.0.0.0/customeraccountname to map to the view for the customer account page.
UPDATE:
Here is the code that ended up working in routes.rb, which I discovered after looking at the examples in the answer below:
resources :customer_accounts, :path => '/:id' do
root :action => "show"
member do
get 'disabled'
post 'update_billing'
end
end
If you want to set it up so you have a route like you show, do this:
get '/:id', :to => "customer_accounts#show"
If you want the disabled and update_billing actions underneath this:
get '/:id/disabled', :to => "customer_accounts#disabled"
post '/:id/update_billing', :to => "customer_accounts#update_billing"
Alternatively (and much neater):
scope '/:id' do
controller "customer_accounts" do
root :action => "show"
get 'disabled'
get 'update_billing'
end
end

Resources