Routing Error uninitialized constant when I create a new action - ruby-on-rails

I know it is a typical problem. But I was just trying the routing in rails and I get this error:
uninitialized constant UsersController
And I don't know well where is the problem.
The resume of my app is a simple application of a library, where users can book books and see the books they've booked.
Here is my routes.rb
Brickstest2::Application.routes.draw do
resources :books
root "pages#home"
get "home", to: "pages#home", as: "home"
get "inside", to: "pages#inside", as: "inside"
devise_for :users
namespace :admin do
root "base#index"
resources :users
end
resources :books do
get :book_a_book, :as => "reserve"
end
resources :users do
get :booked_books, :as => "reserved", :on => :member
end
end
Actually When I do rake routes I get:
reserved_user_path
GET /users/:id/booked_books(.:format) users#booked_books
And in users_controllers.rb I have:
def booked_books
#user = User.first(params[:user_id])
#return unless #user == current_user
#books = Books.where(:user = #user)
end
The link to booked_books:
<%= link_to "My books", user_reserved_path(:user_id => current_user.id)%>
And finally my users/booked_books.html.erb:
<h1>My books</h1>
<%= #books.each do |book|%>
<p><%= book.name %>
<% end %>
Thanks in advance.

Have you declared a controller for your User resource that subclasses ApplicationController?
# app/controllers/users_controller.rb
class UsersController < ApplicationController
Note that the precise naming convention for a plural resource route for the User model is UsersController (note the s). I'm guessing that you've named your controller class UserController, which won't work for your use-case.
UPDATE:
Since you've declared a controller namespace, you'll want to declare your controller class like so:
# app/controllers/admin/users_controller.rb
class Admin::UsersController < ApplicationController
This should resolve any uninitialized constant UsersController errors involving your namespace.

Related

Rails 5 Routing Error - uninitialized constant DashboardController

I'm building out a multi-tenant site and am using Ryan Bigg's https://leanpub.com/multi-tenancy-rails as a guide. I am stuck at creating a simple scoped route; I keep getting the error Rails 5 Routing Error - uninitialized constant DashboardController. I am sure I am missing something simple as syntax has changed a bit since the final release of the publication. Does my code below look as it should--right now I am just looking to get the dashboard index page to show?
controllers/accounts/base_controller.rb
module Accounts
class BaseController < ApplicationController
before_action :authenticate_user!
end
end
controllers/accounts/dashboard_controller.rb
module Accounts
class DashboardController < Accounts::BaseController
def index
end
end
end
views/accounts/dashboard/index.html.rb
<section class="bg--secondary space--sm conversation">
<div class="container">
<div class="row">
<div class="col-md-6">
<h1>Dashboard</h1>
</div>
</div>
</div>
</section>
routes.rb
constraints(SubdomainRequired) do
scope module: 'accounts' do
root to: 'dashboard#index', as: :account_root
end
end
Rails.application.routes.draw do
devise_for :users
constraints(SubdomainRequired) do
root to: 'dashboard#index', as: :account_root
end
get '/accounts/new', to: 'accounts#new', as: :new_account
post '/accounts', to: 'accounts#create', as: :accounts
root 'welcome#index'
end
I made multi tenant project soon and I had used lvh.me for development environment. Try the following solution:
config/initializers/subdomain_constraint.rb
class SubdomainConstraint
def initialize
#domain_development = 'lvh.me'
end
def matches?(request)
if Rails.env.development?
#domain_development == request.domain
end
end
end
routes.rb
constraints(SubdomainConstraint.new) do
match '', to: 'dashboard#index', constraints: {subdomain: /.+/}, via: [:get]
end
I'm not sure you can define a class in the routes.rb file. Perhaps if you create a new file called lib/subdomain_required.rb and moved
class SubdomainRequired
def self.matches?(request)
request.subdomain.present? && request.subdomain != 'www'
end
end
to that file instead of putting it in your routes.rb.

Rails - no method error for new form

I'm sure that there is a simple solution to this problem, but I can't for the life of me see what I am doing wrong - it's been a few months since I've worked on a Rails project, I must be forgetting something important.
I'm just trying to create a basic Rails form, but I am getting a no method path error when I navigate to the new form page.
This is for my Report model...
routes.rb
resources :report, only: [:new, :create], path_names: {new: ''}
report_controller.rb
def new
#report = Report.new
end
report/new.html.erb
<%= form_for #report do |f| %>
<% end %>
Navigating to http://localhost:3000/report yields
undefined method `reports_path'
Just to be comprehensive, here's the model...
class Report < ActiveRecord::Base
belongs_to :user
belongs_to :weather
belongs_to :feature
end
and the routes
report_index POST /report(.:format) report#create
new_report GET /report(.:format) report#new
I'm sure this is an amateur mistake... but I can't see what it is!
You need to change your routes to include a :show path if you want to be able to go to /report.
The path that I believe you are looking for is localhost:3000/reports/new
Oh for the love of god. It was a pluralization issue. The files should appear and be named as follows:
routes.rb
resources :reports, only: [:new, :create], path_names: {new: ''}
reports_controller.rb
class ReportsController < ApplicationController
def new
#report = Report.new
end
end
And the view files should all be in a folder called 'reports', not 'report'. The model is just the singular report.rb.

Adding namespace in Rails and routing error

I tried to add namespace in my RoR project.
It works as expected:
controller:
class Dashboard::CategoriesController < ApplicationController
...some code
end
routes.rb
namespace "dashboard" do
resources :categories
end
but it doens'y work:
class Dashboard::UsersController < ApplicationController
...some code
end
class Dashboard::CardsController < ApplicationController
...some code
end
routes.rb:
namespace "dashboard" do
resources :users do
resources :cards do
member do
post 'review'
end
end
end
end
it throws an routing error: uninitialized constant CardsController
what's wrong?
Rails auto loads class if its name match file name. Error indicates that CardsController class is not loaded, so most probably you named your controller file wrongly. It should be app/controllers/dashboard/cards_controller.rb.
First of all, you'll be better making your routes more compacted:
#config/routes.rb
namespace :dashboard do
resources :users do
resources :cards do
post :review #-> domain.com/dashboard/users/:user_id/cards/1
end
end
end
The error it self will likely be caused by the way in which you're trying to call the controller. Typically, you'll receive errors with the namespace prepended to the class name (Dashboard::CardsController). In this instance, it just says CardsController.
You'll need to look at how you're calling the route.
Specifically, I presume you're using a form_for - which will build the route for you. If this is the case, you'll need to use the namespace within the form_for declaration itself:
<%= form_for [:dashboard, #user, #card], url: dashboard_user_cards_review(#user, #card) do |f| %>

Unable to use inherited_resources' polymorphic belongs_to with namespaced controllers

I am facing an issue with inherited_resources when using a polymorphic nested resource, one of whose parents is a namespaced controller. Here is an abstract example:
# routes.rb
resources :tasks do
resources :comments
end
namespace :admin do
resources :projects do
resources :comments
end
end
# comments_controller.rb
class CommentsController < InheritedResources::Base
belongs_to :projects, :tasks, :polymorphic => true
end
When I access /admin/projects/1/comments, I get this error:
ActionController::RoutingError at /admin/projects/1/comments
uninitialized constant Admin::CommentsController
Now if I define the controller as Admin::CommentsController, I would need to move the file under controllers/admin which will in turn throw up an error for the url /tasks/1/comments
Is there a way I can fix this?
Why not keep CommentsController where it is and make a separate controller for admin in admin/comments_controller.rb? that inherits from it?
class Admin::CommentsController < CommentsController
before_filter :do_some_admin_verification_stuff
# since we're inheriting from CommentsController you'll be using
# CommentsController's actions by default - if you want
# you can override them here with admin-specific stuff
protected
def do_some_admin_verification_stuff
# here you can check that your logged in used is indeed an admin,
# otherwise you can redirect them somewhere safe.
end
end
The short answer to your question is mentioned here in the Rails Guide.
Basically you have to tell the route mapper which controller to use because the default is not there:
#routes.rb
namespace :admin do
resources :projects do
resources :comments, controller: 'comments'
end
end
That will take care of your routing problem, which is actually probably not related to Inherited Resources.
On the other hand, I have been unable to use Inherited Resources as well, in cases of a nested controller inside a namespace. I've moved away from that gem because of this.
I created something that might be interesting to you: a controller concern that will define all of the useful route helpers that inherited resources gives, in a way that accounts for namespaces. It's not smart enough to handle optional or multiple parentage, but it spared me a lot of typing long method names.
class Manage::UsersController < ApplicationController
include RouteHelpers
layout "manage"
before_action :authenticate_admin!
before_action :load_parent
before_action :load_resource, only: [:show, :edit, :update, :destroy]
respond_to :html, :js
create_resource_helpers :manage, ::Account, ::User
def index
#users = parent.users
respond_with [:manage, parent, #users]
end
def show
respond_with resource_params
end
def new
#user = parent.users.build
respond_with resource_params
end
# etc...
end
And then inside my views:
td = link_to 'Show', resource_path(user)
td = link_to 'Edit', edit_resource_path(user)
td = link_to 'Destroy', resource_path(user), data: {:confirm => 'Are you sure?'}, :method => :delete
Hope that helps!

Routing Error - custom controller

I have a has many through association.
Firms have many Users through Follows.
I want Users to be able to Follow Firms. - I am using Devise for the users.
I have the following action in my firms controller.
def follow
#firm.users << current_user
end
in my routes.rb
resources :firms do
post :follow, on: :member
end
and in my firms view
<%= link_to "Follow", follow_firm_path(#firm), method: :post %>
However when I keep getting the following Routing Error in the browser
No route matches {:action=>"follow", :controller=>"firms"}
Rake Routes confirms the following
follow_firm POST /firms/:id/follow(.:format) firms#follow
Any ideas what the problem may be?
Many thanks
Edit: Controller code
class FirmsController < ApplicationController
before_filter :authenticate_user!, :except => [:show, :index]
def index
#firm_names = Firm.all.map &:name
direction = params[:direction]
direction ||= "ASC"
#firms = Firm.order("name #{direction}")
respond_to do |format|
format.html # index.html.erb
format.js
end
end
def follow
#firm.users << current_user
end
I am using the follow action in a partial in the index view.
everything looks good and this should work perfectly. Except that I see a typo in the following line
<%= link_to "Follow", follow_firm_path(#firm), method: :post %>
after the :method there should an => not a : . this will make the link a get request not a post request, that might be the issue, try using a simple link and replace post will get in your routes.rb just to test if the issue is arising due to this.
you can also test route methods from the console
rails c
app.follow_firm_path(2)
I noticed you also have an error in your routes, there should be an => not a : after :on
resources :firms do
post :follow, :on => member
end
You should define methods like this...
resources :firms do
collection
post :follow, on: :member
end
end
I think if this method does not create anything its type should be get.
Try it

Resources