I have an application in which a club has_many locations. Clubs & their locations can only be edited within an admin namespace.
I am trying to pre-load the club into the controller so that all actions deal with that club only.
The routes are nested; however, in the locations controller, it does not find the Club model. What am I doing wrong?
routes.rb
namespace :admin do
resources :clubs do
resources :locations
end
end
club.rb
class Club < ActiveRecord::Base
belongs_to :membership
has_many :users
has_many :locations
#accepts_nested_attributes_for :locations
end
admin/locations_controller.rb
class Admin::LocationsController < ApplicationController
before_filter :load_club
protected
def load_club
#club = Club.find(params[:club_id])
end
end
Also, lastly: What is wrong with my routes that it is not looking for the locations controller in admin/clubs/locations? I'm not sure if that is part of the problem.
from rake routes
admin_club_locations POST /admin/clubs/:club_id/locations(.:format) admin/locations#create
new_admin_club_location GET /admin/clubs/:club_id/locations/new(.:format) admin/locations#new
edit_admin_club_location GET /admin/clubs/:club_id/locations/:id/edit(.:format) admin/locations#edit
admin_club_location PUT /admin/clubs/:club_id/locations/:id(.:format) admin/locations#update
DELETE /admin/clubs/:club_id/locations/:id(.:format) admin/locations#destroy
It probably looks up the Club model within the current Admin namespace. You could try:
def load_club
#club = ::Club.find(params[:club_id])
end
Related
In Rails 3, I have these:
# shop.rb
class Shop < ActiveRecord::Base
TYPES = %w(cafe restaurant)
end
# shops_controller.rb
class SpotsController < ApplicationController
def cafe
end
def restaurant
end
end
# routes.rb
resources :shops do
resources :reviews, :photos
member do
get *Shop::TYPES
end
end
The idea is to generate get routes based off the Shop::TYPES array:
get :cafe
get :restaurant
In any case when I create another new type in Shop, I won't have to update my routes.
I am upgrading to Rails 4. What is the equivalent to get *Shop::TYPES, because I couldn't find the answer?
You can Try this
resources :shops do
resources :reviews, :photos
member do
get 'cafe'
get 'restaurant'
end
end
You can also try this Link
I have a controller for "Productions" and if you go to localhost/productions you see an index page, you can click show and view the show page for that particular productions.
Each production has a unique ID like 036ea872f9011a7c, I want my users to be able to add items to a production like follows:
localhost/productions/036ea872f9011a7c/fixtures/add
localhost/productions/036ea872f9011a7c/positions/add
localhost/productions/036ea872f9011a7c/dimmers/add
localhost/productions/036ea872f9011a7c/channels/add
localhost/productions/036ea872f9011a7c/etc/add
You should build a route with the necessary parameters like this:
Suppose we have tasks that we assign to a project
model project.rb:
class Project < ActiveRecord::Base
has_many :tasks, through: :project_task
end
model task.rb
class Task < ActiveRecord::Base
has_many :projects, through: :project_task
end
routes.rb
...
resources :projects do
member do
get 'affect_task/:task_id', action: 'affect_task', as: :affect_task
end
end
projects/show.haml
= link_to "task_name", affect_task_project_path(task_id: #task_id, project_id: #project_id)
controller.rb
...
def affect_task
...
CollaboratorTask.create(task_id: params[:task_id], project_id: params[:project_id])
...
end
...
Of course this is an example so you understand..
I have a resources :shops
which results in a /shops, /shops/:id, etc
I know I can scope collection or members with
resources :shops do
scope ":city" do
# collection and members
end
end
or do it before with
scope ":city" do
resources :shops
end
But I can't figure out how to make the route be on all members (including the standard REST ones) and collection, like so
/shops/:city/
/shops/:city/:id
As per your use case and question, you are trying to have logically wrong routes. You have shops within the city, NOT city within the shop.
Firstly you should normalize your database. You should create another table cities and replace your city attributes with city_id in shops table.
You need has_many and belongs_to association between cities and shops.
# Models
class City < ActiveRecord::Base
has_many :shops
... # other stuff
end
class Shop < ActiveRecord::Base
belongs_to :city
... # other stuff
end
Routes
resources :cities do
resources :shops
end
It will generate routes like:
POST /cities/:city_id/shops(.:format) shops#create
new_city_shop GET /cities/:city_id/shops/new(.:format) shops#new
edit_city_shop GET /cities/:city_id/shops/:id/edit(.:format) shops#edit
city_shop GET /cities/:city_id/shops/:id(.:format) shops#show
PATCH /cities/:city_id/shops/:id(.:format) shops#update
PUT /cities/:city_id/shops/:id(.:format) shops#update
DELETE /cities/:city_id/shops/:id(.:format) shops#destroy
Logically, these routes will show that in which city the particular shop exists.
Namespace
You may wish to consider including a namespace
Since you're trying to pull up the cities for shops (IE I imagine you want to show shops in Sao Paulo), you'd be able to do this:
#config/routes.rb
namespace :shops do
resources :cities, path: "", as: :city, only: [:index] do #-> domain.com/shops/:id/
resources :shops, path: "", only: [:show] #-> domain.com/shops/:city_id/:id
end
end
This will allow you to create a separate controller:
#app/controllers/shops/cities_controller.rb
Class Shops::CitiesController < ApplicationController
def index
#city = City.find params[:id]
end
end
#app/controllers/shops/shops_controller.rb
Class Shops::ShopsController < ApplicationController
def show
#city = City.find params[:city_id]
#shop = #city.shops.find params[:id]
end
end
This will ensure you're able to create the routing structure you need. The namespace does two important things -
Ensures you have the correct routing structure
Separates your controllers
I am still new to rails and I am trying to figure out how to implement a polymorphic association without using a nested route or form. I tried searching but everything seemed to be about nesting forms or adding comments, which is not what I am trying to do.
Here are my models
Article.rb
class Article < ActiveRecord::Base
belongs_to :articable, polymorphic: true
end
Organization.rb
class Organization < ActiveRecord::Base
has_many :articles, as: :articable
end
People.rb
class People < ActiveRecord::Base
has_many :articles, as: :articable
end
I want to implement a 'New Article' link from a Organization or People show page and have the correct article_id and article_type entered. What would the correct syntax be to generate this link?
Thanks!
Routes:
resource :people do
resource :articles
end
resource :organizations do
resource :articles
end
ArticlesController:
def create
article = Article.new(params[:article])
if params[:people_id]
people = People.find(params[:people_id])
people.articles << article
else
organization = Organization.find(params[:organization_id])
organization.articles << article
end
article.save
end
Organizations view:
link_to new_organization_article_path(#organization)...
I have namespaced model Equipment::Feature and namespaced controller in my admin part Admin::Equipment::FeaturesController. Model is generic and is used as from within :admin namespace and for public website. I've set up the routing for :admin and :equipment namespaces
namespace :admin do
namespace :equipment do
resources :features
end
end
Which gives me following routes:
admin_equipment_features GET /admin/equipment/features(.:format) admin/equipment/features#index
POST /admin/equipment/features(.:format) admin/equipment/features#create
new_admin_equipment_feature GET /admin/equipment/features/new(.:format) admin/equipment/features#new
edit_admin_equipment_feature GET /admin/equipment/features/:id/edit(.:format) admin/equipment/features#edit
admin_equipment_feature GET /admin/equipment/features/:id(.:format) admin/equipment/features#show
PUT /admin/equipment/features/:id(.:format) admin/equipment/features#update
DELETE /admin/equipment/features/:id(.:format) admin/equipment/features#destroy
Pretty standard stuff. But when I address /admin/equipment/features it throws uninitialized constant Admin::Equipment::FeaturesController::Equipment exception
#index action in my Admin::Equipment::FeaturesController looks like
def index
#features = Equipment::Feature.all
end
It did seem to work, until I declared Admin::Equipment namespace. Before it was like Admin::EquipmentFeaturesController
I guess this is some sort of namespace collision, but I don't get it - where does it come from?
Thanks in advance!
UPDATE Feature model (uses STI pattern)
class Equipment::Feature < ActiveRecord::Base
attr_accessible :category_id, :name_en, :name_ru, :type
belongs_to :category, :class_name => 'Equipment::Category'
has_many :item_features, :class_name => 'Equipment::ItemFeature'
has_many :items, :through => :item_features
translates :name
end
class FeatureBoolean < Equipment::Feature
end
class FeatureNumeric < Equipment::Feature
end
class FeatureString < Equipment::Feature
end
class FeatureRange < Equipment::Feature
end
UPDATE2
Fixing #index action as per answer below resolved the issue. New code:
def index
#features = ::Equipment::Feature.all
end
I think it's now looking for Feature in Admin::Equipment, rather than in ::Equipment
Try specifying that there is no namespace, i.e.
def index
#features = ::Equipment::Feature.all
end
Please create folder like this app/controllers/admin/equipment/features.rb
And then edit your controller name to Admin::Equipment::FeaturesController
class Admin::Equipment::FeaturesController < ActiveRecord::Base
end