working with views using rails new backend Rails 5 - ruby-on-rails

I started with rails 5, I am noob in rails. I want to create a simple API, but I want to have views (such as active admin). I found the autogenerated API using the code 'rails new backend' command.
Is there a way to autogenerate views and not only Json response using this command?

I may not have the answer, but I found this which may be a better answer to the question.
Approach:
Subclass APIController from ActionController::API, rather than ApplicationController, make ApplicationController inherit from ActionController::Base.
You may include the Rack::MethodOverride middleware.
I'd try to build something similar to this in the coming week, largely to learn about ActiveAdmin and some newer Rails methodologies.

Using the standard ActiveAdmin interface won't work with an API app because those (by definition) cut away the presentation layer, i. e. all the gems for views/js/etc.
But it will work the other way around: --api is almost a subset of a full rails application and comes with, for example, json rendering by default. I say 'almost' because a few details need to be adjusted, such as (probably) cors and csrf settings.
You can get get to a functioning rails 5 app serving .json in about a minute:
rails new foo
rails db:setup
rails generate scaffold Post title:string body:text
rails db:migrate
rails server
-> http://localhost:3000/posts/index.json
Apart from reading the docs and a few tutorials, you should generate two applications, one with --api and one without, add model/views/controller scaffold and just walk through the diff. Then you can mix&match the customizations for api-mode into your app.

Enabling Active Admin for Rails 5 API application
1. Separate view-rendering controllers from API controllers
Active Admin requires ApplicationController to inherit from ActionController::Base.
API controllers should still inherit from ActionController::API
Use the following
class ApplicationController < ActionController::Base
class APIController < ActionController::API
where any API-specific controllers inherit from APIController.
2. Enable flash middleware
Inside config/application.rb
module MyApp
class Application < Rails::Application
# ...
# add this =>
config.middleware.use ActionDispatch::Flash
end
end
3. (For Devise authentication) Enable session management
Inside config/application.rb
module MyApp
class Application < Rails::Application
# ...
# add these =>
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore
end
end
Here is the full guide

Related

Versioning API Helpers in Ruby on Rails

We have a versioned API that follows all the conventions of Rails API versioning. i.e
module API::V4
class Test < ApiController
end
end
But is there a proper way to version helpers? The current helpers directory looks like something like this:
app
|__helpers
|__helper_a.rb
|__helper_b.rb
and all helpers are defined modules.
Is there a way to do this?
module Helpers::V2
class HelperA
end
end
I tried creating a directory app/helpers/v2/helper_a.rb, adding app/helpers/helpers.rb and defining module Helpers But for some reason rails always fails to see Helpers::V2::HelperA
Rails searches each subdirectory of app starting from the subdirectory. app/models/foo/bar.rb contains Foo::Bar not Models::Foo::Bar. app/controllers/api/v4/test.rb contains Api::V4::Test, not Controllers::Api::V4::Test.
So app/helpers/v2/helper_a.rb contains V2::HelperA.
module V2
module HelperA
end
end
If you want to relate the helper version with your API version, it makes sense to mirror the directory structure.
# app/helpers/api/v2/helper_a.rb
# A helper for API v2.
module Api
module V2
module HelperA
end
end
end
Note that it's Api to follow Rails conventions. The autoloader will map app/helpers/api/v2/helper_a.rb to Api::V2::HelperA. It might work with the Rails 5 autoloader, but not the Rails 6 autoloader.
If we use API::V2::HelperA...
[1] pry(main)> API::V2::HelperA
NameError: uninitialized constant API
Did you mean? Api

Controllers into completely different directory

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

Organizing models/controllers and classes in rails in subfolders

I am working in a Rails project in which i have used the below names for model/controller and class files
/app/models/friends/friend.rb
/app/controllers/friends/friends_controller.rb
/lib/classes/friends/friend.rb
I tried to add all the models, controllers and class files in autoload path in application.rb.
But i am facing issues since the class names are same.
How should i handle this? and organize files in such a way that files are organized with name spaces.
Thanks,
Balan
A much better approach would be to use Rails Engines & divide your app in isolated modules.
rails plugin new friends --full --mountable --dummy-path spec/dummy
the above command will generate a full mountable engine with isolated namespace, meaning that all the controllers and models from this engine will be isolated within the namespace of the engine. For instance, the Post model later will be called Friends::Post, and not simply Post. to mount this app inside your main rails app, you need do two things:
Add entry to Gemfile
gem 'friends', path: "/path/to/friends/engine"
And then add route to config/routes.rb
mount Friends::Engine, at: "/friends"
For more information on this approch, checkout:
Rails Guide to Engines
Taming Rails Apps with Engines
RailsCast #277 Mountable Engines
The class names are same but path's are different, and you don't need to add classes to autoload except /lib/classes/friends/friend.rb
Did you tried the following way:
# app/models/friends/friend.rb
class Friends::Friends
#...
end
# Friends::Friends.new
# app/controllers/friends/friends_controller.rb
class Friends::FriendsController < ApplicationController
#...
end
# lib/classes/friends/friend.rb
module Classes
module Friends
class Friends
#...
end
end
end
# Classes::Friends::Friends.new
To add lib files to autoload add following to your applicaion.rb
config.autoload_paths += %W(#{config.root}/lib)

How to prepend rails view paths in rails 3.2 (ActionView::PathSet)

I am trying to prepend views to the rails view array e.g.
prepend_view_path("#{Rails.root}/app/views/custom/blah")
This works fine, however in my test suite I keep seeing
DEPRECATION WARNING: process_view_paths is deprecated and will be removed from Rails 3.2.
After a bit of research I see mention of ActionView::PathSet, but cannot find any help searching google or in the Rails API documentation. I need to know how to use this new way of prepending paths in rails 3.2
I would really like to get rid of this warning. Any thoughts?
If it is dynamic (set on a per-request basis):
class ApplicationController < ActionController::Base
before_filter :set_view_path
def set_view_path
prepend_view_path "#{Rails.root}/app/views/custom/blah"
end
end
I think it went to AbstractController::ViewPaths, but still available from controller - should be without deprecation.
If you prepend static fixed path:
# config/application.rb
config.paths.app.views.unshift("#{Rails.root}/app/views/custom/blah")

'RuntimeError: route set not finalized' when calling Rails.application.routes.generate() or Rails.application.routes.recognize_path()

I use the Rails.application.routes.generate() and Rails.application.routes.recognize_path() in my application to disassemble and generate URLs using the Rails routing table. I never had a problem with this using the Rails 2.3.x series but since Rails 3 (specifically 3.1.3) I've been getting the following error when invoking these commands
RuntimeError: route set not finalized
Two questions :
Why? Am I getting this - my application is up and running and handling other requests. Why are the routes not finalized by now?
To solve this error I call Rails.application.routes.finalize! before invoking either of these methods as it seems to work. Are there any implications to doing this?
In Rails 3, you don't use this technic. You need include Rails.application.routes.url_helpers after you can use your named_route
class User < ActiveRecord::Base
include Rails.application.routes.url_helpers
def my_own_url
user_url(self)
end
end

Resources