My controller is as follows:
class CommentLoaderController < ApplicationController
respond_to :js
def show
puts 'here'
#client_id = params[:id]
respond_with #client_id
end
end
It loads a .js file which has some .erb markup in it. I'd like to load a CoffeeScript file, compiled to JS on the fly. Is this possible with Rails 3?
I think this blog post that one of my colleagues wrote today might help
http://www.storm-consultancy.com/blog/development/random-bits/todays-gotcha-when-coffeescript-templates-in-rails-work-in-development-but-not-production/
It turns out that Rails won’t compile CoffeeScript templates by
default, but you can install the Coffeebean gem and it magically
works.
Related
I have a single-page application written in React with Ruby on Rails back-end (API mode). Rails is also serving static files. I'm pointing Rails router to public/index.html, so my SPA could manage his own routing with react-router. This is common practice in order to make direct links and refresh to work.
routes.rb
match '*all', to: 'application#index', via: [:get]
application_controller.rb
class ApplicationController < ActionController::API
def index
render file: 'public/index.html'
end
end
The problem is this doesn't work in API mode. It's just an empty response. If I change the parent class to ActionController::Base everything works as expected. But I don't want to inherit the bloat of full class, I need slim API version.
I've tried adding modules like ActionController::Renderers::All and AbstractController::Rendering without success.
If I change the parent class to ActionController::Base everything works as expected. But I don't want to inherit the bloat of full class, I need slim API version.
Yes, if you serve index from ApplicationController, changing its base class would affect all other controllers. This is not good. But what if you had a specialized controller to serve this page?
class StaticPagesController < ActionController::Base
def index
render file: 'public/index.html'
end
end
This way, you have only one "bloated" controller and the others remain slim and fast.
You could do
render text: File.read(Rails.root.join('public', 'index.html')), layout: false
I usually just redirect_to 'file path'.
def export
# When the route coming to get 'some_report/export', to: 'greate_controller#export'
# The file where you write or preparing, then you can redirect some path like : http://localhost:3000/public/tmpfile/report20210507.xlsx
# And it will just redirect the file for you
file_path = "public/tmpfile/report20210507.xlsx"
redirect_to "#{root_url}#{file_path}"
end
For this example
root_url = "http://localhost:3000/"
This should work, and allow you to keep inheriting from ActionController::API--
class ApplicationController < ActionController::API
def index
respond_to do |format|
format.html { render body: Rails.root.join('public/index.html').read }
end
end
end
The render logic changed for ActionController::API with Rails 5.
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'
how do I add a dynamic redirect? I tried it in ApplicationController and ApplicationHelper with no success.
I want something like this:
def dynamic_path
if current_user.admin?
admin_path
else
overview_path
end
end
What's the best practice for that?
Thanks!
Edit:
Oh, I forgot to mention that I want to put this into my gem which is used by two different applications and both should use this method. Where exactly should I put it?
Try putting this in the ApplicationController and then add a helper_method line at the top of the application controller like so:
helper_method :dynamic_path
def dynamic_path
redirect_to (current_user.admin? ? admin_path : overview_path)
end
The helper_method line makes this method available in all your views and controllers.
Use redirect_to:
def dynamic_path
redirect_to (current_user.admin? ? admin_path : overview_path)
end
Update: And since it sounds like you're trying to store this helper module in an external gem you'll need to ensure your module gets loaded as an ActionView helper, which can be done automatically by using a Railtie in your gem. See
How do I extract Rails view helpers into a gem?
I just wrote a small module in my Rail 3.0.0 application lib folder:
module AdminFilters
def verify_is_admin
if current_user.nil? || current_user.role != User::Role::ADMIN
redirect_to :root, :alert => "You don't have enough permissions"
end
end
end
And in order to make it available for all my controllers :
class ApplicationController < ActionController::Base
protect_from_forgery
require "admin_filters"
include AdminFilters
end
If I remove the require line, rails complains like this :
uninitialized constant ApplicationController::AdminFilters
Is it the normal behavior ? I thought that any rb file in the lib folder was auto-loaded by rails ...
Yes, it was auto-loaded in Rails 2.x.x, but Rails 3 doesn't load files from lib/ anymore. You should consider placing your files into the config/initializers directory.