Rails 3 routing inside a controller - ruby-on-rails

I have just switched to rails from padrino/sinatra so the routing stuff puzzles me.
I have defined,
namespace :admin do
resources :teachers, :students, :lessons
end
in my routes.rb file, and when i run rake routes command it gives me,
admin_teachers GET /admin/teachers(.:format) admin/teachers#index
POST /admin/teachers(.:format) admin/teachers#create
new_admin_teacher GET /admin/teachers/new(.:format) admin/teachers#new
edit_admin_teacher GET /admin/teachers/:id/edit(.:format) admin/teachers#edit
admin_teacher GET /admin/teachers/:id(.:format) admin/teachers#show
PUT /admin/teachers/:id(.:format) admin/teachers#update
DELETE /admin/teachers/:id(.:format) admin/teachers#destroy
admin_students GET /admin/students(.:format) admin/students#index
POST /admin/students(.:format) admin/students#create
new_admin_student GET /admin/students/new(.:format) admin/students#new
edit_admin_student GET /admin/students/:id/edit(.:format) admin/students#edit
admin_student GET /admin/students/:id(.:format) admin/students#show
PUT /admin/students/:id(.:format) admin/students#update
DELETE /admin/students/:id(.:format) admin/students#destroy
admin_lessons GET /admin/lessons(.:format) admin/lessons#index
POST /admin/lessons(.:format) admin/lessons#create
new_admin_lesson GET /admin/lessons/new(.:format) admin/lessons#new
edit_admin_lesson GET /admin/lessons/:id/edit(.:format) admin/lessons#edit
admin_lesson GET /admin/lessons/:id(.:format) admin/lessons#show
PUT /admin/lessons/:id(.:format) admin/lessons#update
DELETE /admin/lessons/:id(.:format) admin/lessons#destroy
The problem is, i can't figure out how to respond a request to admin/students#update? I know how to respond to admin#teachers, in my admin controller i create a teachers function. But how to respond to admin/teachers/index? Or maybe where to respond? In which file? In which function or class?

For admin/students#update Rails will look for the action here:
class Admin::StudentsController < ApplicationController
def update
# update here
end
end
You can generate this file with:
rails generate controller admin/students update
Which will write to:
app/controllers/admin/students_controller.rb

Related

Rails getting routes name in Route.rb with controller actions

I'm a real beginner of rails.
Can I get multiple routes from one controller + many actions?
For example,
resources :something
get "something#index", "something#show", "something#update"...etc.
I'm just curious if there is a command to get route name from the actions.
For example, in a controller named "pledges",
class PledgesController < ApplicationController
def home
end
def abc
end
def defg
end
def hijk
end
end
Can any commands get "pledges#home", "pledges#abc", "pledges#defg","pledges#hijk" ?
To add custom, "non-RESTful" routes to a resource, you could do the following:
resources :pledges do
collection do
get :foo
end
member do
put :bar
end
end
collection-defined routes will produce results against Pledge as a whole – think the index route.
member-defined routes will produce results against an instance of Pledge – think the show route.
This would produce the following routes for you:
foo_pledges GET /pledges/foo(.:format pledges#foo
bar_pledge PUT /pledges/:id/bar(.:format) pledges#bar
pledges GET /pledges(.:format) pledges#index
POST /pledges(.:format) pledges#create
new_pledge GET /pledges/new(.:format) pledges#new
edit_pledge GET /pledges/:id/edit(.:format) pledges#edit
pledge GET /pledges/:id(.:format) pledges#show
PATCH /pledges/:id(.:format) pledges#update
PUT /pledges/:id(.:format) pledges#update
DELETE /pledges/:id(.:format) pledges#destroy
You will have to define all of the custom actions, if there are not restful (but I would highly recommend that you follow the rest conventions). For example:
get 'pledges' => 'abc'
post 'pledges' => 'defg'
put 'pledges' => 'hijk

Rails - using namespace controllers to organize files

I am trying to learn about namespacing.
I've asked a few questions on this topic previously, but I'm not understanding what is going on.
I have made a folder in my controller's folder called 'features'. In it, I have saved a file called app_roles_controller.rb.
The first line of that controller is:
class Features::AppRolesController < ApplicationController
The purpose of the features folder is so I can organise my files better (that's it).
In my routes.rb, I have tried:
resources :app_roles, :namespace => "features", :controller => "app_roles"
I have also tried:
namespace :features do
resources :app_roles
end
I have a model (top level) called app_role.rb and I have a views folder saved as views/features/app_roles which then has the index, show etc files in it. The table in my schema is called 'app_roles".
When I rake routes for app_roles, I get:
Paths Containing (app_role):
app_roles_path GET /app_roles(.:format)
app_roles#index {:namespace=>"features"}
POST /app_roles(.:format)
app_roles#create {:namespace=>"features"}
new_app_role_path GET /app_roles/new(.:format)
app_roles#new {:namespace=>"features"}
edit_app_role_path GET /app_roles/:id/edit(.:format)
app_roles#edit {:namespace=>"features"}
app_role_path GET /app_roles/:id(.:format)
app_roles#show {:namespace=>"features"}
PATCH /app_roles/:id(.:format)
app_roles#update {:namespace=>"features"}
PUT /app_roles/:id(.:format)
app_roles#update {:namespace=>"features"}
DELETE /app_roles/:id(.:format)
app_roles#destroy {:namespace=>"features"}
I can't understand what it is that I'm doing wrong.
When I try:
http://localhost:3000/app_roles#index
I get an error that says:
uninitialized constant AppRolesController
When I try:
http://localhost:3000/features/app_roles#index
I get an error that says:
No route matches [GET] "/features/app_roles"
I'm looking for a plain English explanation of how to set this up. I've tried the programming ruby book (several times over).
Please, can you help me understand what needs to happen to introduce organisational files in my rails app?
It looks like your other attempt was actually correct. As outlined in the Rails documentation, if you want to generate routes for the resource app_roles under the namespace features you can add the following to your routes.rb file:
namespace :features do
resources :app_roles
end
Now, you run rake routes you will see the following:
Prefix Verb URI Pattern Controller#Action
features_app_roles GET /features/app_roles(.:format) features/app_roles#index
POST /features/app_roles(.:format) features/app_roles#create
new_features_app_role GET /features/app_roles/new(.:format) features/app_roles#new
edit_features_app_role GET /features/app_roles/:id/edit(.:format) features/app_roles#edit
features_app_role GET /features/app_roles/:id(.:format) features/app_roles#show
PATCH /features/app_roles/:id(.:format) features/app_roles#update
PUT /features/app_roles/:id(.:format) features/app_roles#update
DELETE /features/app_roles/:id(.:format) features/app_roles#destroy
The first line for example means that if you make a GET request to /features/app_roles it will be routed to the index action in the features/app_roles controller.
In other words, if you visit http://localhost:3000/features/app_roles it will route the request to index action that is located in app/controllers/features/app_roles_controller.rb which it expects to have the class Features::AppRolesController.
So your app/controllers/features/app_roles_controller.rb file should look something like this:
class Features::AppRolesController < ApplicationController
def index
end
end

Rails routing: uninitialized constant ClanController

I have some problems with routing custom controller actions
Routes:
resources :clans do
get 'leave' =>'clan#leave_clan'
get 'dismiss' =>'clan#dismiss_clan'
get 'kick_from_clan/:user_id' =>'clan#kick'
get 'invite/:user_id' =>'clan#invite'
get 'join' =>'clan#join'
end
namespace :admin do
resources :clans
resources :users
end
I know i have clans both in admin namespace and also without but that is how i need it, actions are completely different in them.
And I use a generated route as clan_join_path(clan).
This action results in the next error:
uninitialized constant ClanController
Directory structure:
/app
/controller
/admin
/ClansController.rb
/ClansController.rb
EDIT:
Also invite and kick routes are not generated as expected.
*no path* GET /clans/:clan_id/kick_from_clan/:user_id(.:format) clan#kick
*no path* GET /clans/:clan_id/invite/:user_id(.:format) clan#invite
Any suggestion to the edit part?
You're defining a resource called clans and I presume you have a controller also called ClansController (note the puralization). If you don't have this controller, you'll be wanting to create it.
You probably therefore need to pluralize your routes:
resources :clans do
get 'leave' =>'clans#leave_clan'
get 'dismiss' =>'clans#dismiss_clan'
get 'kick_from_clan/:user_id' =>'clans#kick'
get 'invite/:user_id' =>'clans#invite'
get 'join' =>'clans#join'
end
Also make sure your controller is named clans_controller.rb (pluralized).
You can use member do ... end to properly route based on type of action
resources :clans do
member do
get :leave
get :dismiss
#etc
end
end
This will define the routes as clans/:id/leave clans/:id/dismiss
Check if your clans_controller.rb is intentionally not plural.
resources :clans do
get 'leave' =>'clans#leave_clan'
get 'dismiss' =>'clans#dismiss_clan'
get 'kick_from_clan/:user_id' =>'clans#kick'
get 'invite/:user_id' =>'clans#invite'
get 'join' =>'clans#join'
end
app/controllers/clans_controller.rb
class ClansController < ApplicationController
end

Accessing a Module Resource with Rails 4.x

I am using rails 4.1 with Casein CMS: https://github.com/russellquinn/casein
I have setup a Post Model, view and controllers within casein, but I would like to access the Posts outside of casein, possibly under another route called blog
I have tried and tried reworking my routes and controllers, and have an array of errors to list. Someone here might know just the trick to get this working, and was hoping some could help me, or at least explain to me what should be happening or what I might be doing wrong.
What Casein adds to the routes is this:
#Casein routes
namespace :casein do
resources :posts
end
And I'd like to match the index and show actions to => /blog. How might I write this correctly in my routes.rb.
My controller, I have basically extracted the actions from the Casein's PostsController, and along with including the Casein Module have tried to simple list all the posts.
Here is what my blogs_controller's index action looks like:
class BlogsController < ApplicationController
module Casein
def index
#casein_page_title = 'Posts'
#posts = Post.order(sort_order(:title)).paginate :page => params[:page]
end
end
end
By the end I'd also like to take blogs to blog, but I think can take it from there, but if anyone has any suggestions, that would be much appreciated.
You might be asking for this, but your question is not very clear.
If you want to have the following routes and use the same controller for each.
Prefix Verb URI Pattern Controller#Action
casein_posts GET /casein/posts(.:format) casein/posts#index
POST /casein/posts(.:format) casein/posts#create
new_casein_post GET /casein/posts/new(.:format) casein/posts#new
edit_casein_post GET /casein/posts/:id/edit(.:format) casein/posts#edit
casein_post GET /casein/posts/:id(.:format) casein/posts#show
PATCH /casein/posts/:id(.:format) casein/posts#update
PUT /casein/posts/:id(.:format) casein/posts#update
DELETE /casein/posts/:id(.:format) casein/posts#destroy
blog GET /blog(.:format) casein/posts#index
GET /blog/:id(.:format) casein/posts#show
then your config/routes.rb file should contain
namespace :casein do
resources :posts
end
get '/blog', to: 'casein/posts#index'
get '/blog/:id', to: 'casein/posts#show'
And you need your controller to be app/controllers/casein/posts_controller.rb
But I'd really strongly encourage you to use 2 different controllers, and a concern for the shared methods

Rails route parent ID name and CanCan issue

I'm trying to get a simple route working
/agenda_items/5/feed
To do this, I have the following route setup
resources :agenda_items do
member do
get "/feed", to: "comments#feed"
end
end
In each of my controllers, I'm using CanCan to handle the authentication and it works fine, however on this one action I'm having an issue, which I'm pretty sure is down to railsnaming generation. When I runrake routes`, the route above is produced as
feed_agenda_item /agenda_items/:id/feed(.:format) agenda_items/:id#feed
As far as I can tell, CanCan is expecting the :id parameter, to actually be :agenda_item_id so as a result, my parent resource isn't being loaded.
Is there any way I can get rails to change this so that CanCan will work without me having to manually load and authorize the resource, or is there a way I can get CanCan to change what it's looking for on certain actions?
The problem is that your routes are wrong. You try to create a member action for agenda items which routes to the comments controller. If you want a feed of all the commments from a single agenda item you should do something like this:
resources :agenda_items do
resources :comments do
collection do
get :feed
end
end
end
You should now get the following when running rake routes:
feed_agenda_item_comments /agenda_items/:agenda_item_id/feed(.:format) comments#feed

Resources