I originally posted this as an issue on rails_api GitHub, but am now posting it here due to inactivity.
I'm trying to use rails_admin with a Rails 5 API application. I included extra ActionController modules up to the point that I can either have a functioning rails_admin panel or working API requests. The issue seems to be that rails_admin depends on ActionView::Layouts, which after included causes issues for API requests.
Gemfile:
gem 'rails', '>= 5.0.0.beta3', '< 5.1'
...
gem 'rack-pjax', github: 'afcapel/rack-pjax'
gem 'remotipart', github: 'mshibuya/remotipart'
gem 'kaminari', github: 'amatsuda/kaminari', branch: '0-17-stable'
gem 'rails_admin', github: 'sferik/rails_admin'
I configured my application to use ActionDispatch::Flash:
module MyApp
class Application < Rails::Application
...
config.middleware.use ActionDispatch::Flash
end
end
I configured extra modules for Rails API, ApplicationController:
class ApplicationController < ActionController::API
include Knock::Authenticatable
include Pundit
# RailsAdmin support
include AbstractController::Helpers
include ActionController::Flash
include ActionController::RequestForgeryProtection
include ActionController::MimeResponds
include ActionController::HttpAuthentication::Basic::ControllerMethods
include ActionView::Layouts
end
With these changes the Rails Admin dashboard seems to run fine. However, when I'm trying to access the JSON resources in my application, the following error is thrown:
Error:
BookingsControllerTest#test_should_get_index:
ActionView::MissingTemplate: Missing template bookings/index, application/index with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :haml]}. Searched in:
* "/Users/richard/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/bundler/gems/rails_admin-355dc80f8a20/app/views"
The test code (also tried adding format: :json):
class BookingsControllerTest < ActionController::TestCase
test 'should get index' do
get :index
assert_response :success
end
end
This is the controller code:
class BookingsController < ApplicationController
def index
#bookings = find_bookings
render json: #bookings, include: ['customer', 'client'], meta: meta
end
end
This only happens after I include the ActionView::Layouts module in the top level ActionController::API class to support Rails Admin.
If I were you, I try isolate API and RailsAdmin controllers. I think this must work:
class ApplicationController < ActionController::API
include Knock::Authenticatable
include Pundit
end
class RailsAdminCustomController < ApplicationController
# RailsAdmin support
include AbstractController::Helpers
include ActionController::Flash
include ActionController::RequestForgeryProtection
include ActionController::MimeResponds
include ActionController::HttpAuthentication::Basic::ControllerMethods
include ActionView::Layouts
end
In config/initializers/rails_admin.rb
RailsAdmin.config do |config|
# other config stuff ...
config.parent_controller = '::RailsAdminCustomController'
end
Just check the RailsAdmin::ApplicationController here, and the config settings here.
As of v1.0.0 (released September 2016), Rails Admin now supports Rails 5 API-mode straight out-of-the-box. The gem itself injects the missing middleware to render its views and there is no extra configuration required.
Links:
Using Rails Admin with Rails 5 API application
CHANGELOG
You should have a json view file in this location bookings/index.json.jbuilder
And inside this file something like
bookings/index.json.jbuilder
json.name #bookings.name
json.date #bookings.date
This is another template missing
application/index
but really don't know you app completely. So maybe that's the application layout you implemented using ActionView::Layouts. In that case is asking you to implement a layout page file in the location application/index.
NOTE: Those two file inside the views folder.
Related
I generated an API-only rails app with Rails 5 via rails new <application-name> --api. I've decided I want to include a view for testing some things and am having issues getting a view to load.
I created a users/index.html.erb file with some text and my controller is now simply def index; end but there is nothing appearing when I hit the /users URL. I also tried commenting out the # config.api_only = true in config/application.rb but that didn't affect anything. Any suggestions on how to proceed?
You don't need to uncomment config.api_only = true for this purpose, just inherit your controller from ActionController::Base, or do it in your ApplicationController (default for common rails generation).
Code:
For this controller only YourController < ActionController::Base
For all apllication ApplicationController < ActionController::Base
this is from the ActionController::Metal docs https://apidock.com/rails/ActionController/Metal
it says:
ActionController::Metal by default provides no utilities for rendering >views, partials, or other responses aside from explicitly calling of >response_body=, content_type=, and status=. To add the render helpers >you’re used to having in a normal controller, you can do the following:
class HelloController < ActionController::Metal
include AbstractController::Rendering
include ActionView::Layouts
append_view_path "#{Rails.root}/app/views"
def index
render "hello/index"
end
end
So I've tried it myself and adding just by adding the two modules actually work just fine when using it for ActionController::API
I want to use Jbuilder with Rails 5.0.0.beta1.1 in API mode. Out of the box, it doesn't work, even when creating the app/views directory.
For example, I have:
# app/controllers/tests_controller.rb
class TestsController < ApplicationController
# The requests gets inside the action
def test
end
end
# app/views/tests/test.json.jbuilder
json.test "It works!"
The error I'm getting is
No template found for TestsController#test, rendering head :no_content
I guess I have to change some things in the config files. What do I have to do?
Doing an explicit render from the controller like this works:
render 'controller_name/action.json.jbuilder'
With API mode.
You need include module like bellow
class ApplicationController < ActionController::API
include ActionController::ImplicitRender # if you need render .jbuilder
include ActionView::Layouts # if you need layout for .jbuilder
end
I got the same error, but in my case I had simply forgotten to add the jbuilder gem in the Gemfile:
gem 'jbuilder', '~> 2.5'
I'm having a problem creating an Engine in Rails.
I want to create an engine that uses Devise to share over all my other applications.
I followed the Getting Started guide for Engines at rails website:
http://edgeguides.rubyonrails.org/engines.html
Created an application, required my engine... everything runs just fine.
Then, I run into Devise (I've already installed Devise direct in an application before, but not in an engine) but when I try to use it, by acessing any controller that inherits the before_action authenticate_user! I get this message:
http://i.imgur.com/dIIxgwU.jpg
I really don't understand (I'm starting in Ruby, I'm a CakePHP guy), the route is set, but it can't find it (?).
engine/config/initializers/devise.rb
Devise.setup do |config|
...
config.router_name = :doisbit
config.parent_controller = 'Doisbit::ApplicationController'
end
engine/config/routes.rb
Doisbit::Engine.routes.draw do
...
devise_for :users, class_name: "Doisbit::User", module: :devise
...
end
engine/lib/doisbit/engine.rb
module Doisbit
class Engine < ::Rails::Engine
isolate_namespace Doisbit
end
end
engine/lib/doisbit.rb
require 'doisbit/engine'
require 'devise'
...
engine/doisbit.gemspec
...
Gem::Specification.new do |s|
...
s.add_dependency "devise"
end
engine/app/controllers/application_controller.rb
module Doisbit
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
end
application/config/routes.rb
Rails.application.routes.draw do
...
mount Doisbit::Engine, at: "/doisbit"
end
application/config/environments/development.rb
Rails.application.configure do
...
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end
application/Gemfile
...
gem 'doisbit', path: "C:/.../doisbit"
...
EDIT
Just noticed by accessing /doisbit/users/sign_in I get the form. (duh)
i.imgur.com/anTRK2d.jpg
But... still... by default it routes to /users/sign_in when i'm not logged in.
What I'm missing?
I'm getting undefined method 'authorize_actions_for' in the controller when using rails-api with the Authority gem. Any ideas what I need to include? Here's my code:
Gemfile:
...
gem 'authority', '~> 2.9.0'
gem 'rails-api', '~> 0.1.0'
...
app/authorizers/session_authorizer.rb:
class SessionAuthorizer < ApplicationAuthorizer
def deletable_by?(user)
user.sessions.include?(resource)
end
end
app/controllers/v1/sessions_controller.rb:
class V1::SessionsController < ApplicationController
authorize_actions_for Session
...
end
Include Authority::Controller
As we discussed on Github, authorize_actions_for is defined in Authority::Controller.
In a normal Rails app, that module gets included into ActionController::Base by Authority's railtie.rb. Apparently the railtie isn't being required when using rails-api (maybe the Rails constant isn't defined?).
You can include the appropriate module yourself, though:
class ApplicationController < ActionController::Base
include Authority::Controller
end
I started using comatose to handle content on my site but am having problems using it with my existing authentication using a generic Authlogic config.
In the readme he sites an example for configuring it with Restful Authentication and I'm wondering how I would do the same within a general Authlogic setup?
#environment.rb
Comatose.configure do |config|
# Includes AuthenticationSystem in the ComatoseController
config.includes << :authenticated_system
end
http://github.com/darthapo/comatose
I think a better way to do it is moving the auth methods out into a module, and include that from both ApplicationController and comatose. Example:
Put your auth methods into user_sessions_helper:
module UserSessionsHelper
module AuthMethods
private
...
def require_user
...
Then include the module in your ApplicationController:
class ApplicationController < ActionController::Base
include UserSessionsHelper::AuthMethods
...
And finally in the comatose config as well (environment.rb):
Comatose.configure do |config|
config.admin_includes << "UserSessionsHelper::AuthMethods"
config.admin_authorization = :require_user
end