Controllers into completely different directory - ruby-on-rails

I'm trying to build an admin panel to my rails application, but want to keep my admin controllers away from my other controllers. Is there anyway I can have a admin folder in my app folder which contains controllers just for admin stuff.
Thanks in advance.

Yes, sure.
You can put all the admin related controllers in app/controllers/admin/ directory.

Yes, you can do this by namespacing your controllers under an admin module.
The easiest way to set this up is to use the rails generator, and prefix your resource with "admin":
rails generate controller admin/user
Type rails g controller for specific helps.
Here's a page from the guide with more info: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing

If you want to keep your admin completely separate, you can use an engine. To generate the engine, do:
rails plugin new admin --mountable
Then in your main app's routes file, you can mount the engine with:
mount Admin::Engine => "/admin"
See http://guides.rubyonrails.org/engines.html for complete details on engines.

Thats very simple, usually it makes sense to put those in app/controllers/admin but if you use this, you'll need to use a namespace. Rails will then autoload these classes.
It's a good practice to make an ApplicationController per namespace (I'm calling it base controller) like this:
module Admin
class BaseController < ApplicationController
end
end
and here's an exapmle controller:
module Admin
class ExampleController < Admin::BaseController
def example
end
end
end

Related

How to use usermodel from mainApp in custom engine

I've created an RoR-App and I want to add a simple blog as engine that is already mountet to /blog where users can have their own blog. Now I didn't find anything how I can use the model user.rb in my blog engine.
In my main app I can use current_user.username but in my engine I can't use it.
There are (at least) two ways to achieve this:
Inherit your controller class from the main application's ApplicationController:
class MyEngine::ApplicationController < ::ApplicationController
end
This way it will have access to all the same helpers that have already been configured there. As a downside, this might drag in unwanted functionality, too.
Manually include the Devise controller helpers:
class MyEngine::ApplicationController
include Devise::Controllers::Helpers
define_helpers(Devise.mappings[:user])
end

Creating Rails Controller In Sub-directory

How do I create a rails Events controller in a different directory other than the default:
app/controllers/events_controller.rb
I need to create in app/controllers/api/events_controller.rb
I created the api sub-directory and did cd in terminal to api. When I created the controller it still generated in the default app/controllers/.
Thanks.
You can namespace your controllers (generated like this: rails g controller API::Events).
Put your controller in the api directory within your controllers directory and name the controller's class like this:
class API::EventsController < ApplicationController
More details discussed here: https://stackoverflow.com/a/9946410/1026898
If that is not what you want to do, rails tends to lean in the direction of not putting that controller in a different directory.
It doesn't hurt anything to do so, it's just a bit odd. The rails generators, by default, are built to put the controllers in the conventional directory.
If you want to change where they are generated you will have to update the generator.
To do that with rails generators:
rails g controller API::Events

Rails separate backend and frontend

I am really confused about rails namespaces. I tried to create my own admin namespace so added namespace to routes, this works good. Then i added folder admin into controllers.
Admin::Controller
this is how my controllers in that folder looks.
but here comes the problem. How can i separate Helpers? rails automatically loads all helpers. I disabled that in config but now it wont load it manually like module Admin::ApplicationHelper.
How about next things what needs to be separated? Like i18N, sessions, flashes? Is there a tutorial for this problem? Im using Rails 4. Thanks for advices
As you've noticed rails defaults to including all helpers into all views. You can turn this off by adding
config.application_controller.include_all_helpers = false
This will result in only ApplicationHelper and the controller's helper being included. Adding
helper :foo
To a controller would result in FooHelper being included in addition to the defaults. If there are helpers that should be loaded for all of the admin controllers then add this to their base class. If you need anything more than this then consider using a rails engine (with the isolate_namespaces option turned on)
You only namespace controllers, views, models, and helpers, not everything else you mentioned. If you disabled autoloading helpers you'll have to manually require each one that you need:
require 'admin/admin_helper'
class Admin::Controller < ActionController::Base
... code ...
Same goes for any other helper such as application_helper, etc. Everything else, sessions, flashes, i18n and so on are merely methods from ActionController::Base that all controller's inherit. There's no namespacing these.
Going back to the helpers question: you namespace them the same way you namespace the controllers:
# app/helpers/admin/admin_helper.rb
module Admin::AdminHelper
... code ...
end
And then just require it in your admin controllers if you need to. I'd keep autoloading helpers enabled in order to forego having to require them everywhere.

Rails mountable engine and overriding another engine

I'm in the proces of converting my standard Rails app to an mountable engine. The app is comparable to a standard blogging app and i want every model, controller and view to be extendable hence my choice for a mountable engine.
One of the gems i use is Devise which is as far as i understand a sort of a mountable engine itself. It can be used inside a mountable engine as stated here.
I'm able to use it partially within my engine. Everything is working fine including some Devise controller i override like this one:
# config/routes.rb
Bbronline::Engine.routes.draw do
devise_for :users, class_name: "Bbronline::User", module: :devise,
controllers: { registrations: "bbronline/devise_overrides/registrations"}
...
# controllers/bbronline/devise_overrides/registrations_controller.rb
require_dependency "bbronline/application_controller"
module Bbronline
class DeviseOverrides::RegistrationsController < Devise::RegistrationsController
def new_intermediair
#user = User.new
end
...
The correct view 'views/bbronline/devise_overrides/registrations/new_intermediair.html.haml' is also correctly loading as expected.
However my issue is that the views that i override without a custom controller are not properly loaded. For example the view that should the login view is located in views/bbronline/devise/sessions/new.html.haml and is not loaded. Instead the standard Devise login view gets loaded i.e. devise-2.1.0/app/views/devise/sessions/new.html.erb
Of course i could solve this problem by overriding every controller with my own controller like i did with the registrations_controller above but this seems very ugly. Is overriding every controller the way to do this? Is there a more convenient way to override views from an mountable engine from within another mountable engine?
If you don't want to adjust the config.railties_order in every app that uses your engine, just require 'devise' on top of your lib\my_engine\engine.rb file.
The view_paths are in incorrect order. Checking the view paths of Devise::SessionsController shows:
Devise::SessionsController.view_paths
=> #<ActionView::PathSet:0x007fa1bf0e36f8 #paths= [/Users/harmdewit/Dropbox/Code/projects/brightin/bbr-online/bbr-online-gem/test/‌​dummy/app/views,
/Users/harmdewit/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/devise-2.1.‌​0/app/views,
/Users/harmdewit/Dropbox/Code/projects/brightin/bbr-online/bbr-online-gem/app/vi‌​ews]>
The last path of the mountable engine should come before the middle devise path. The solution is setting the loading priority in application.rb like this:
#test/dummy/config/application.rb (the app that uses my mountable engine)
...
config.railties_order = [Blog::Engine, :main_app, :all]
...
This is also documented in the rails api: http://api.rubyonrails.org/classes/Rails/Engine.html#label-Loading+priority
Thanks to José Valim for pointing in the right direction.
I need more information. Which controller are you defining and from which controller is it inheriting from? Which view is being rendered and which one did you expect to render? Also, .view_paths is your friend so try in your rails console the following:
Devise::SessionsController.view_paths
YourApp::SomeDeviseController.view_paths
This will give you a better idea of where each controller is searching for templates.

ruby on rails sub directory inside in the 'Views' main directory

am a newbie in ruby on rails and am stuck with a simple problem of routing.
I have my controller 'sub' and the 'Views' folder containing the add,edit,new erb files.
In my routes file, i have 'map.resources :subs'.
Until now, everything is fine.
Problem:
I moved the add,edit,new erb files into a subfolder called 'admin' inside the 'Views' main directory.
I have no idea how to call those erb files from that 'admin' subdir.
By default, it is looking for /app/views/subs/index.html.erb, and i want it to look in /app/views/subs/admin/index.html.erb
Please can anyone tell me how to do this.
Many many thanks
I suggest a different approach because it seems what you want to do is admin routing. In your routes.rb write
namespace :admin do
resources :subs
end
then put your views in the subdirectory views/admin/subs
also, put your controller in the subdirectory controllers/admin and namespace them with "Admin" too, e.g.
class Admin::StubsController < Admin::ApplicationController
your_code_goes_here
end
of course, then you need an application_controller.rb in the controllers/admin dir as well. But you cold also derive from ApplicationController then that is not necessary.
your controller can be called through the url /admin/subs
does that help?
You could explicitly render your templates within your controller actions, like this:
render :template => "subs/admin/index"
I'm a beginner in RoR.
What I wanted was to group all views (such as a mobile friendly version) in 1 folder but not end up with an extra namespace OR create new method in controllers. localhost:3000/posts calls:
class Post < ActiveRecord
and not
class Admin::Post < ActiveRecord
BUT load the views in views/android/posts/index.html.erb
Because this was my Google first hit, the link below is to an alternative answer that took sometime for me to find.
Rails: Elegant way to structure models into subfolders without creating submodules

Resources