When I want to show default welcome page by routes.rb,
I can add route like this:
root "rails/welcome#index"
Then, I want to render the same template in my controller out of curiosity.
The template is in rails/railties/lib/rails/templates/rails/welcome/index.html.erb
I thought `render "controller/action" works for my own files,
but it doesn't seem to work for built-in files.
def index
render "rails/welcome/index" # This shows error `Missing template rails/welcome/index`.
end
So, Is there a handy way to render built-in template?
Yes you can render the rails welcome page from your controller by using the Rails::WelcomeController
class WelcomeController < Rails::WelcomeController
end
Don't define the index method in WelcomeController. Rails will pick the index method of Rails::WelcomeController and will render the default welcome page.
Related
Premise: I'm quite new to Rails. I'm trying to render a partial in the application layout that will have to display some Event objects. The partial will have to be displayed in every page of the application (it's basically a sidebar). I am aware that I should pass a local variable to the partial, like
<%= render partial: "shared/aside", locals: {events: #events} %>
But this will only work if I define #events in every single controller of the application. Is there a way of setting it globally?
It might be worth noting that events might not be the only resource needed to the partial.
You could do a before action in the application controller. The before action would go at the top of the file, the private method at the bottom
class ApplicationController < ActiveController::Base
# Place at top of file
before_action :set_events
...your other code...
# Place at bottom of file
private
def set_events
#events = Event.all
end
Is it possible to override Rails' render behavior for :html responses? I'd like to always render the same template (ignoring the magic view finding).
I'm writing a single page app, and this seems like it should be possible...basically if it's requested as :json it should render JSON, but if it's requested as :html it should pass the data on to the same view no matter what (where it will be rendered as JSON in the body).
Try to delete the yield part on your application.html.erb, then you will alway get the application.html.erb without any partials.
What if you define one single view and then after every action on every controller you render that view? Like this:
app/controllers/home_controller.rb
class HomeController < ApplicationController
def home
end
end
app/views/home/home.html.erb
<!-- Whatever html code and script tags here -->
app/controllers/another_controller.rb
class AnotherController < ApplicationController
def action
render "home/home"
end
end
You could even define an after_filter
Edit
I tried this and it works. The after filter doesn't seem to work though.
Why not pass the JSON data as an instance variable?
controller
#json_data = whatever_model.to_json
application.html.erb
<script>
<%= #json_data %>
</script>
Is it possible to reuse jbuilder-template in another controller method? In other words: how to explicitly say controller method to use concrete jbuilder-template?
From Rails guide.
Rendering an Action's Template from Another Controller.
What if you want to render a template from an entirely different
controller from the one that contains the action code? You can also do
that with render, which accepts the full path (relative to app/views)
of the template to render. For example, if you're running code in an
AdminProductsController that lives in app/controllers/admin, you can
render the results of an action to a template in app/views/products
this way
def my_action
# some code here
render "products/show"
end
def my_action
# some code here
render "products/show.json"
end
or
def my_action
# some code here
render "show.json"
end
without the .json it will try to render an html file.
I am not able to share views among multiple controllers in Ruby ob Rails application.
Please help.
you can even use partials or explicitly render another template in controller's action.eg: -
def UsersController < ApplicationController
def index
#records = User.all
render '/products/index' # instead of user's index i rendered product's index template
end
end
You can use this in the view you are trying to render the other view
abc - The name of the folder in which the other view exists (views/abc/view_name.html.erb)
xyz - The name of the view
<%= render :template "abc/xyz" %>
I am writing a Ruby on Rails application with a controller called "pages_controller" that is responsible for displaying pages to users. There are 3 different types of pages that can be displayed, and different things have to happen on the back end in each case, so I decided to break the functionality out into 3 methods within the controller. When the user requests a page, the "show" method is called, which figures out whether the page:
1. Belongs to the user
2. Belongs to another user, and can be viewed by the user requesting it
3. Belongs to another user, and cannot be viewed by the user requesting it (unauthorized)
The appropriate method is then called from there to display the page. The code looks something like this:
def show
if (something)
showMine
elsif (something else)
showAnother
else
showUnauthorized
end
end
def showUnauthorized
respond_to do |format|
format.html # showUnauthorized.html.erb
end
end
def showMine
respond_to do |format|
format.html # showMine.html.erb
end
end
def showAnother
respond_to do |format|
format.html # showAnother.html.erb
end
end
I am getting a template missing error because rails wants to render a view when "show" is called, but I do not want any views to be rendered when "show" is called. I simply want "show" to call the correct method from there, and the corresponding view for that method (showMine, showAnother, or showUnauthorized) to be rendered. How can I do this? Or am I going about this the wrong way entirely?
You need to declare these new actions that you have created in the routes file, as they don't belong to the RESTful routes.
I sugest to keep only the show action in your controller and create the IFs in the show view using the render method to include the partials(_showMine.html.erb, showAnother.html.erb, showUnauthorized)
example:
show view:
if (something)
<%= render 'showMine' %>
elsif (something else)
<%= render 'showAnother' %>
else
<%= render 'showUnauthorized' %>
end
I hope it helps...
I basically agree with Samy's comment, but here's some background:
The method that tells Rails what view to use is render. If there's no call to that method in your show method, Rails assumes you have a view called show.xxx.xxx, e.g. show.html.erb, that is supposed to be rendered. Note that it doesn't assume template will be prefixed with show because that's the name of the method. It assumes it will be show because that's the name of the action. The name of the action is passed to the controller as part of the request; it's not simply derived from the name of whatever method has a respond_to block in it.
All the respond_to blocks do is specify different view templates based on the MIME type of the request, but since you never call render, all of those extra methods are still trying to call the show view (show.html.erb in every case), because you never told Rails to render any other view, and the action name is show.
So, instead of the respond_to blocks, just call render [some_view] in each of your other methods.
This might not be the clearest answer, but I'd suggest also reading the following:
http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to/
It describes what respond_to does, in particular how it keys off the action name to determine what view to render.