Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic namespaced controllers w/ fallback in Rails

I have a somewhat bizarre requirement for a new Rails application. I need to build an application in which all routes are defined in multiple namespaces (let me explain). I want to have an application in which school subjects (math, english, etc) are the namespaces:

%w[math english].each do |subject|
  namespace subject.to_sym do
    resources :students
  end
end

This is great and it works but it requires me to create a namespaced StudentsController for each subject which means if I add a new subject then I need to create a new controller.

What I would like is to create a Base::StudentsController and if, let's say the Math::StudentsController exists then it will be used and if it doesn't exist, then we can dynamically create this controller and inherit from Base::StudentsController.

Is this something that is possible? If so then how would I go about implementing this?

like image 374
Kyle Decot Avatar asked May 09 '13 17:05

Kyle Decot


People also ask

How many types of routes are there in Rails?

Rails RESTful Design which creates seven routes all mapping to the user controller. Rails also allows you to define multiple resources in one line.

What are resources in Rails routes?

Any object that you want users to be able to access via URI and perform CRUD (or some subset thereof) operations on can be thought of as a resource. In the Rails sense, it is generally a database table which is represented by a model, and acted on through a controller.

What is namespace in Rails routes?

This is the simple option. When you use namespace , it will prefix the URL path for the specified resources, and try to locate the controller under a module named in the same manner as the namespace.

What is match in Rails routes?

Rails routes are matched in the order they are specified, so if you have a resources :photos above a get 'photos/poll' the show action's route for the resources line will be matched before the get line. To fix this, move the get line above the resources line so that it is matched first.


1 Answers

With routes defined this way:

%w[math english].each do |subject|
  scope "/#{subject}" do
    begin
      "#{subject.camelcase}::StudentsController".constantize
      resources :students, controller: "#{subject}::students", only: :index
    rescue
      resources :students, controller: "base::students", only: :index
    end
  end
end

rake routes outputs:

students GET /math/students(.:format)    base::students#index
         GET /english/students(.:format) english::students#index

if english/students_controller.rb is present and math/students_controller. is absent.

like image 87
Shamir K. Avatar answered Oct 02 '22 12:10

Shamir K.