So I want when I access: site.com/panel to look into /app/controller/panel/index_controller.rb
Before I start I'm new to ruby, I started a couple hours ago
So in my routes.rb I have this
namespace :panel do
root 'index#index'
resources :index
end
And I created a file called index_controller.rb in /app/controller/panel/index_controller.rb which looks like this
class IndexController < ApplicationController
def index
#foo = "Foo"
end
end
Now when I go to site.com/panel I get this: superclass mismatch for class IndexController
What I did wrong?
Also can I setup different views and layout here to use for the controllers inside /app/controller/panel/*_controller.rb
replace this
class IndexController < ApplicationController
with
class Panel::IndexController < ApplicationController
update:
to automatically generate namespaced controller you can use rails build in generator like this
rails g controller panel/users
this will generate Panel::Users < ApplicationController controller under app/controllers/panel/users_controller.rb
Since you've namespaced the index resource routes within panel, you'll need to prefix your IndexController declaration to reflect this:
# app/controllers/index_controller.rb
class Panel::IndexController < ApplicationController
Then, you can similarly reflect the namespace in your filesystem in order to get Rails to properly invoke the correct views:
/app/views/panel/index/index.html.erb
/app/views/panel/index/show.html.erb
... etc
A note: the Rails convention is that routes that are declared as resources should be named plural, as this denotes an entirely resourceful class. Thus, according to this paradigm, index should actually be indexes. However, I suspect you may mean to use a singular route, in which case the declaration would be as follows:
namespace :panel do
resource :index
end
Which creates the following singular routes (which may conform better to what you're trying to accomplish):
panel_index POST /panel/index(.:format) panel/indices#create
new_panel_index GET /panel/index/new(.:format) panel/indices#new
edit_panel_index GET /panel/index/edit(.:format) panel/indices#edit
GET /panel/index(.:format) panel/indices#show
PUT /panel/index(.:format) panel/indices#update
DELETE /panel/index(.:format) panel/indices#destroy
Related
Quick question, I’m building a rails app that has the ability to contain multiple “features” one of those being rsyslog, other features could be any other software. Below is the current construct:
Controllers:
features/
features/rsyslog/
features/rsyslog/rsyslog_inputs_controller.rb
features/rsyslog/rsyslog_outputs_controller.rb
features/rsyslog/rsyslog_rules_controller.rb
Routes:
resources :features do
scope module: "features/rsyslog” do
resources :rsyslog_inputs
resources :rsyslog_outputs
resources :rsyslog_rules
end
end
(controller code does not work here)
Controller code:
class Features::RsyslogInputsController < ApplicationController;end
class Features::RsyslogOutputsController < ApplicationController;end
class Features::RsyslogRulesController < ApplicationController;end
I’m curious, given that there are multiple features and I’d like to keep each features controllers nested in a directory specific to that feature.. i.e. (rsyslog containing all of the rsyslog controllers) as opposed to building the structure like so:
features/
features/rsyslog_inputs_controller.rb
features/rsyslog_outputs_controller.rb
features/rsyslog_rules_controller.rb
How does that translate to the controller code class definition? doing this:
Class Features::Rsyslog::RsyslogInputsController < ApplicationController; end
(note the addition of Rsyslog above)
RubyMine it’s getting pissy with a “expected end of line” on the second set of “::” in the class definition... However, the routes work.. Am I missing something here? is this just my IDE being weird?
app/features/rsyslog/inputs_controller.rb
Should define
class Features::Rsyslog::InputsController < ApplicationController
...
end
Not
class Features::Rsyslog::RsyslogInputsController < ApplicationController
...
end
Then:
scope :features do
scope :rsyslog do
resources :inputs, controller: 'features/rsyslog/inputs'
resources :outputs, controller: 'features/rsyslog/outputs'
resources :rules, controller: 'features/rsyslog/rules'
end
end
Which yields:
inputs GET /features/rsyslog/inputs(.:format) features/rsyslog/inputs#index
POST /features/rsyslog/inputs(.:format) features/rsyslog/inputs#create
new_input GET /features/rsyslog/inputs/new(.:format) features/rsyslog/inputs#new
edit_input GET /features/rsyslog/inputs/:id/edit(.:format) features/rsyslog/inputs#edit
input GET /features/rsyslog/inputs/:id(.:format) features/rsyslog/inputs#show
PATCH /features/rsyslog/inputs/:id(.:format) features/rsyslog/inputs#update
PUT /features/rsyslog/inputs/:id(.:format) features/rsyslog/inputs#update
DELETE /features/rsyslog/inputs/:id(.:format) features/rsyslog/inputs#destroy
outputs GET /features/rsyslog/outputs(.:format) features/rsyslog/outputs#index
POST /features/rsyslog/outputs(.:format) features/rsyslog/outputs#create
new_output GET /features/rsyslog/outputs/new(.:format) features/rsyslog/outputs#new
edit_output GET /features/rsyslog/outputs/:id/edit(.:format) features/rsyslog/outputs#edit
output GET /features/rsyslog/outputs/:id(.:format) features/rsyslog/outputs#show
PATCH /features/rsyslog/outputs/:id(.:format) features/rsyslog/outputs#update
PUT /features/rsyslog/outputs/:id(.:format) features/rsyslog/outputs#update
DELETE /features/rsyslog/outputs/:id(.:format) features/rsyslog/outputs#destroy
rules GET /features/rsyslog/rules(.:format) features/rsyslog/rules#index
POST /features/rsyslog/rules(.:format) features/rsyslog/rules#create
new_rule GET /features/rsyslog/rules/new(.:format) features/rsyslog/rules#new
edit_rule GET /features/rsyslog/rules/:id/edit(.:format) features/rsyslog/rules#edit
rule GET /features/rsyslog/rules/:id(.:format) features/rsyslog/rules#show
PATCH /features/rsyslog/rules/:id(.:format) features/rsyslog/rules#update
PUT /features/rsyslog/rules/:id(.:format) features/rsyslog/rules#update
DELETE /features/rsyslog/rules/:id(.:format) features/rsyslog/rules#destroy
I'm running into the infamous No Method Error. I've worked my way through a number of examples here on STOF but I can't see an error in my code that stands out. I've checked that rake routes matches what I think should be happening and the paths provided from using resources in the routes.db file seem to be correct. I know I'm missing some small detail but I can't for the life of me see it now. Any help would be appreciated.
My Controller code:
class GenevarecordsController < ApplicationController
def index
#genevarecords = GenevaRecord.all.page(params[:page]).per(5)
end
def new
#genevarecord = GenevaRecord.new
end
end
My routes:
Rails.application.routes.draw do
root 'genevarecords#index'
resources :genevarecords
end
You have a naming discrepency between your model and your controller / routes.
your model is GenevaRecord, underscored makes it geneva_record. However your controller only has a single capital letter at the beginning: Geneverecords which underscored would be genevarecords. Therefore when you pass your model to the form it tries to use a controller / routes helpers with the same naming format as the model, which would be geneva_records_controller ie. GenevaRecordsController.
What you need to do is match your controller and routes to the same naming format as your model:
class GenevaRecordsController < ApplicationController
#...
end
Rails.application.routes.draw do
#...
resources :geneva_records
end
You need to take Did you mean? section seriously,
Anyway, if you closely look at ruby syntax following is the representation for the class name,
AbcDef and equivalent snake case is abc_def
In your case,
Your model is named as GenevaRecord but your controller is GenevarecordsController
change it to GenevaRecordsController, also you need to match it's equivalent snake case in routes...
Rails.application.routes.draw do
root 'geneva_records#index'
resources :geneva_records
end
So, when you pass #genevarecord to the form it is initialized as GenevaRecord.new and searches for geneva_records_path which is undefined because you have defined it as genevarecords_path which doesn't match you model (resources)..
Hope it helps in understanding..
I have read some articles, and i know, that it's bad to inherit more than 2 level deep resources, but let's forget now about it.
let's imagine, i have such model:
car_brand
car_model
car_type
in route i could write something like this:
namespace :admin do
resources :car_brands do
resources :car_models do
resources :car_types
end
end
end
but i didn't find any good article, how to generate my controller's and view, with such schema,
what i need to write in controller class header, something like: class
Admin::CarBrands::CarModelsController < ApplicationController
or what? I need to clear understand this moment, each sub-model view must be in subfolder view, or how?
Admin::CarTypesController < ApplicationController in controllers/admin folder as car_types_controller.rb
Run rake routes and take a look at this line, for example:
/admin/car_brands/:car_brand_id/car_models/:car_model_id/car_types(.:format)
This is the uri pattern that will map Admin::CarTypesController#index metod. In params hash, you will find :car_brand_id and :car_model_id.
what i need to write in controller class header, something like: class
Admin::CarBrands::CarModelsController < ApplicationController
Partly yes and partly no. Yes, in that you've namespaced routes i.e. within namespace :admin and No, because nested resources do not mean namespaced Controllers as CarBrands::CarModelsController.
Since all resources are within the namespace admin, you'd generate all the controllers as follows:
rails g controller admin/car_brands
rails g controller admin/car_models
rails g controller admin/car_types
Executing each command above would place a controller class and view directory and other test specific files in their corresponding directories. Your question is more towards controllers and views so the directories of concerns are:
- app/controllers/admin/
- app/views/admin/car_brands/
- app/views/admin/car_models/
- app/views/admin/car_types/
Your controller declaration for CarBrandsController would then look like:
class Admin::CarBrandsController < ApplicationController
...
end
With these setup, it's now up to you how you want to manage each controller as a resource. If you nest your car_types within car_models then that the methods in car_models controller will also be expecting car_type_id in parameter. If you don't nest car_types resource then the resource is a standalone resource on it's own and does not have dependencies on any other resources.
This is driving me crazy! I have the two models Lion and Cheetah. Both inherit from Wildcat.
class Wildcat < ActiveRecord::Base; end
class Lion < Wildcat; end
class Cheetah < Wildcat; end
STI is used here.
They all get handled through the controller WildcatsController. There, I have a before_filer to get the type of wildcat from the params[:type] and all the other stuff to use the correct class.
In my routes.rb, I created the following routes:
resources :lions, controller: 'wildcats', type: 'Lion'
resources :cheetahs, controller: 'wildcats', type: 'Cheetah'
If I now want to use the path helpers, that I get from the routes (lions_path,lion_path,new_lion_path, etc.), everything is working as expected, except the show and the new paths. For example lions_path returns the path /lions. The new path returns /lions/new?type=Lion. Same with the show path. When I try to enter /lions/new to my root domain it correctly adds the type param in the background.
So, my question is, why does Rails add the type parameter to the url if I use the path helper? And why only for new and show?
I am running Rails 4.0.0 with Ruby 2.0 using a fresh Rails app.
Why using type? Why not use inherited controllers?
resources :lions
resources :cheetahs
Then
class LionsController < WildCatsController
end
class CheetahController < WildCatsController
end
class WildCatsController < ApplicationController
before_filter :get_type
def index
#objs = #klass.scoped
end
def show
#obj = #klass.find(params[:id])
end
def new
#obj = #klass.new
end
# blah blah
def get_type
resource = request.path.split('/')[0]
#klass = resource.singularize.capitalize.constantize
end
I just had this problem. You could try to shutdown the server, remove the /tmp directory and restart.
Rails routes and controller parameters
I'm having an error with my routes/resources and controllers.
I have the following in the routes.rb:
# routes.rb
resources :users do
resource :schedule
end
And I have a schedule_controller.rb inside controllers/users/ set up as I think it should be:
class Users::ScheduleController < ApplicationController
# Controller methods here...
end
Running a rake:routes shows
user_schedule POST /users/:user_id/schedule(.:format) schedules#create
new_user_schedule GET /users/:user_id/schedule/new(.:format) schedules#new
edit_user_schedule GET /users/:user_id/schedule/edit(.:format) schedules#edit
GET /users/:user_id/schedule(.:format) schedules#show
PUT /users/:user_id/schedule(.:format) schedules#update
However, navigating to /users/:user_id/schedule is returning the following error:
uninitialized constant SchedulesController
My only thoughts on what the problem could be are that is has something to do with nested resources or declaring a single resource and I'm going wrong somewhere.
I'm using the helper
new_user_schedule_path(current_user)
when linking to my 'new' view.
It should be SchedulesController, not Users::ScheduleController. Controllers should only be namespaced when the route is namespaced with namespace. Controller names should also always be plural.
What you're creating is a nested resource, not a namespaced one.
Is the namespacing of the SchedulesController intentional? i.e. do you really mean to do this?
class Users::SchedulesController < ApplicationController
Or are you only doing that because schedules are a "sub-thing" from users?
The reason I ask this is because typically within Rails, nested resource controllers aren't namespaced. You would only namespace a controller if you wanted to modify the controllers in a special way under a namespace. A common example of this would be having some controllers under an admin namespace, inheriting from a BaseController within that namespace that would restrict only admins from acessing those controllers.
Option 1
If you didn't intentionally namespace this controller, then you want to remove the Users:: prefix from your controller, and move it back to app/controllers/schedules_controller.rb, the helpers back to app/helpers/schedules_helper.rb and the views back to app/views/schedules. Perhaps you ran a generator which also generated a Users::Schedule model, which should also need to be renamed to Schedule and moved back to app/models/schedule.rb.
Option 2
If you did intentionally namespace this controller, then you want to do this in your routes:
namespace :users do
resources :schedules
end
Leave everything that's been generated as it should be.
In your routes.rb you need to specify the controller like this:
resources :users do
resource :schedules, controller: 'users/schedules'
end
replace resources :users to
namespace :users
Because your schedule controller is inside users folder.
class Users::ScheduleController < ApplicationController
# Controller methods here...
end