New route in resource generates instead of params[:id] params[:patient_id] - ruby-on-rails

I added a new route to one of my resources:
resources :patients do
get 'warte'
end
This generates:
patient_warte_path GET /patients/:patient_id/warte(.:format) patients#warte
patients_path GET /patients(.:format) patients#index
new_patient_path GET /patients/new(.:format) patients#new
edit_patient_path GET /patients/:id/edit(.:format) patients#edit
patient_path GET /patients/:id(.:format) patients#show
.....
What i dont undestand is why the new route generated params[:patient_id!
I mean in my controller i have:
before_action :set_patient, only: [:show, :edit, :update, :destroy, :warte]
def set_patient
#patient = Patient.find(params[:id])
session[:patient] = #patient.id
end
But now of course i get the error: when i call the warte action! Thanks1
Couldn't find Patient without an ID

You are missing a configuration in order to have it use the id. You need to define if it's a :member or :collection action:
resources :patients do
get 'warte', on: :member
end

Related

Rails routing to nested controller

I have one controller for creating category, and I want to have one more nested controller to create language versions of categories. I want to avoid methods like new_language, edit_language, ... and routing on them, I would like to do it the best rails way. But I am new to rails (from Padrino and Sinatra), and I am little bit lost in routing.
I have my controller for categories
module Admin
class CategoriesController < ApplicationController
before_action :authenticate_user!
before_action :find_category, only: [:show, :edit, :update]
layout 'admin'
def index
#categories = Category.all
end
..... all the others CRUD methods ....
end
end
And another controller.
module Admin
class CategoriesLanguageController < ApplicationController
before_action :authenticate_user!
before_action :find_category, only: [:show, :edit, :update]
def new
#category = Category.find(params[:category].to_i)
end
.... all the others CRUD methods ...
end
end
and my routes config.
Rails.application.routes.draw do
devise_for :users
resources :users
namespace :admin do
get '/' => 'dashboard#index'
resources :dashboard, only: [:index]
resources :categories do
collection do
get :publish_category
#get :new_lang
#post :create_lang
#get :edit
#post :update
#get :destroy
end
resources :language, only: [:new, :create, :edit]
end
end
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
root to: "homepage#index"
namespace :api, defaults: { format: 'json' } do
namespace :v1 do
resources :categories, only: [:index]
end
end
end
I would like to have methods new_lang and create_lang under second controller with default names new, create, ....
It generates this
admin GET /admin(.:format) admin/dashboard#index
admin_dashboard_index GET /admin/dashboard(.:format) admin/dashboard#index
publish_category_admin_categories GET /admin/categories/publish_category(.:format) admin/categories#publish_category
admin_category_language_index POST /admin/categories/:category_id/language(.:format) admin/language#create
new_admin_category_language GET /admin/categories/:category_id/language/new(.:format) admin/language#new
edit_admin_category_language GET /admin/categories/:category_id/language/:id/edit(.:format) admin/language#edit
admin_categories GET /admin/categories(.:format) admin/categories#index
POST /admin/categories(.:format) admin/categories#create
new_admin_category GET /admin/categories/new(.:format) admin/categories#new
edit_admin_category GET /admin/categories/:id/edit(.:format) admin/categories#edit
admin_category GET /admin/categories/:id(.:format) admin/categories#show
PATCH /admin/categories/:id(.:format) admin/categories#update
PUT /admin/categories/:id(.:format) admin/categories#update
DELETE /admin/categories/:id(.:format) admin/categories#destroy
but it is not working.
ActionController::UrlGenerationError in Admin::Categories#index
and error is this route:
<td><%= link_to cat.internal_name, edit_admin_category_language_path(id: cat) %></td>
And I don't know how to create these actions in another controller and use url helpers.
Or this is not the best way to do it?
Please any advice?

Delete/Destroy is not working within Rails

I am trying to get a delete button to work using a piece of code I have written within my tags_controller page;
def destroy
#tag = Tag.find(params[:id])
#tag.destroy
redirect_to :back, notice: 'Tag was successfully deleted!'
end
When I run from my local host, it throws an exception as shown below;
Routing Error
No route matches [DELETE] "/admin/tags/37/edit"
Rails.root: /Users/laurenwoodhams/Desktop/PROJECT/RAILS-BLOG/-t
Here is my config routes;
Rails.application.routes.draw do
get '/login' => 'admin/sessions#new'
get '/logout' => 'admin/sessions#destroy'
namespace :admin do
resources :posts
resources :tags, except: [:index]
resources :sessions, only: [:new, :create, :destroy]
resources :administrators, only: [:index, :edit, :update]
end
end
Could you please examine and explain why this may be occurring?
Thank you
DELETE is the HTTP verb (like GET or POST) which means..
To make a link to delete your tag you'll need to do something like this in your view.
<%= link_to "Delete Tag", #tag, method: "delete" %>
Then it should work properly.
P.S.
You can run bin/rake routes to see your routes.

Rails - route index to first module's object

Say I have a module name Server that was created with a scaffold. I want the url 'www.example.com/server/' to be redirected to the first Server object that exists. So for example to be redirected to 'www.example.com/server/2'.
How could this be done with routes.rb (or any other way)?
route.rb:
Rails.application.routes.draw do
resources :servers
end
Server controller:
class ServersController < ApplicationController
before_action :set_server, only: [:show, :edit, :update, :destroy]
# GET /servers
# GET /servers.json
def index
#servers = Server.all
end
....
your can put
redirect_to server_path(Server.first) and return
inside your index method it'll redirect you when ever index action is called.
and just to extent #richfisher's answer (which might be a more appropriate way to do it.)
resources :servers, except: [:index] # this won't generate redundant routes
get '/servers/' => 'servers#first' #note this is now accessible via "server_path" instead of "servers_path" helper.
For what it's worth, I'd do this:
#config/routes.rb
resources :servers, except: :index do
get "", action: :show, id: Server.first.id, on: :collection
end
This will allow you to use the show action in place of index in a super efficient setup:
#app/controllers/servers_controller.rb
class ServersController < ApplicationController
def show
#server = Server.find params[:id]
end
end

Rails routes: GET method redirecting to show method

I have simple controller and routes file.
In my route and controller i have created a module. I wrote a simple method which is redirecting me show. I am not sure why.
Controller
module Seller
class CampaignsController < Seller::BaseController
before_action :confirm_logged_in
def viewAllCampaigns
#campaigns = Campaign.all
end
def show
end
end
end
Routes file
scope module: 'seller' do
#namespace :power do
resources :dashboard, only: [:index]
resources :sessions, only: [:create, :destroy]
resources :campaigns, only: [:index, :create, :show, :update, :destroy]
get 'viewAllCampaigns' => 'campaigns#viewAllCampaigns'
end
Output
Started GET "/campaigns/viewAllCampaigns" for 127.0.0.1 at 2015-10-12 17:39:43 +0500
Processing by Seller::CampaignsController#show as HTML
Parameters: {"id"=>"viewAllCampaigns"}
Rendered seller/campaigns/show.html.erb (0.1ms)
I am hitting http://localhost:3000/campaigns/viewAllCampaigns in browser.
Ideally your routes should be defined like this.
resources :campaigns, only: [:index, :create, :show, :update, :destroy] do
get 'viewAllCampaigns', on: :collection
end
The first comment on the routes.rb file is The priority is based upon order of creation: first created -> highest priority. This is the reason your route is redirecting to show. Rails is treating this url as campain/:id.
Routes are tested in order, from top to bottom. The show route you've added for the campaigns resource will look for urls matching this pattern:
/campaigns/:id
/campaigns/viewAllCampaigns matches this, so it will do the show action., with params[:id] = "viewAllCampaigns"
Move the special case route up above the resources#campaigns route to fix this, then it will catch the url first.
get 'viewAllCampaigns' => 'campaigns#viewAllCampaigns'
resources :campaigns, only: [:index, :create, :show, :update, :destroy]
It takes the following get request as a show action because show expects campaigns/:id, and it assumes 'viewAllCampaigns' is an id in this instance:
/campaigns/viewAllCampaigns
Your link_to should just be pointing to the following:
'/viewAllCampaigns'
Your route structure isn't really RESTful, but that's a separate topic.

rspec ActionController::UrlGenerationError for create action in namespaced admin that is nested

I'm getting this error in my controller spec for my create action
No route matches {:action=>"create", :assessment=>{:course_id=>"1", :curriculum_id=>"1"}, :controller=>"admin/assessments"}
Here is my controller spec:
it "sets the flash success" do
set_current_admin
course = Fabricate(:course)
post :create, assessment: { course_id: course.id, curriculum_id: course.curriculum.id }
expect(flash[:success]).not_to be_blank
end
The error occurs on the post :create.. line.
Here is my create action for assessments:
def create
#assessment = Assessment.new(assessment_params.merge!(course_id: Course.find(params[:course_id]).id))
if #assessment.save
flash[:success] = "You have created your assessment."
redirect_to curriculum_course_assessment_path(#assessment.course.curriculum, #assessment.course, #assessment)
else
...
end
end
And, here is my routing for the assessments:
resources :curriculums, only: [:index, :show] do
resources :courses, only: [:show] do
resources :assessments, only: [:show]
namespace :admin do
resources :assessments, only: [:index, :new, :create, :edit, :update]
end
end
end
Here is the line from my rake routes...
POST /curriculums/:curriculum_id/courses/:course_id/admin/assessments(.:format) admin/assessments#create
When I actually run the create action in the browser, it works fine, so I'm guessing that it's a problem with my spec's syntax. Any advice on this would be much appreciated. (I realize that I'm double-nesting by resources here which is not generally the best practice, but I couldn't find any other way to access the curriculums & courses params.)
You're nesting the course_id and curriculum_id parameters inside an assessment hash - in the route, they are not nested.

Resources