A rails newbie here
I have 2 actions in my controller 1) index 2) refine_existing.
Both of them show the results in the same format.
How do I reuse the index.html.erb file?
When I try the following, it complains about refine_existing.erb not being present.
def refine_existing
...
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #results }
end
end
my index action looks like this
def index
#some logic to get #results
#set some session variables etc.
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #results }
end
end
Do I have to refactor my index view to contain partials that
a) make the headers
b) render #results
and reuse them?
Even though, both index.html.erb and refine_existing.html.erb will look exactly the same
Is there any way I can say in my refine_existing action to use index.erb view?
thanks in advance
By convention, if you don't specify a template name Rails looks for one matching the action. You can override this by calling render explicitly with the desired template name. The only wrinkle is that the path is relative to TEMPLATE_ROOT, which is normally app/views:
def refine_existing
...
respond_to do |format|
format.html { render :template => "<table_name>/index.html.erb" }
end
end
replacing table_name with the "tablized" form of the model. E.g. if your controller is PostsController, then posts. So your template would then live in app/views/posts/index.html.erb -- if you've customized paths somehow adjust as necessary.
Related
If I have the following code, Rails is setup to automatically look in the views folder and find photos/feed.js.erb. But what I want to do is to tell it to run users/feed.js.erb instead.
PhotosController
def feed
#title = "Favorites"
#user_feed_items = current_user.favorites.order('created_at desc').paginate(page: params[:page], per_page: 15)
respond_to do |format|
format.html {
render 'users/feed' }
format.js
end
end
Rails: Render a .js.erb from another controller?
format.js { render :file => "/users/feed.js.erb"}
render accepts the full path (relative to app/views) of the template to render. So, you can just enter users/feed
render "users/feed"
Rails knows that this view belongs to a different controller because of the embedded slash character in the string. If you want to be explicit, you can use the :template option.
render template: "users/feed"
http://guides.rubyonrails.org/layouts_and_rendering.html#using-render
In a Rails 3.2 app, when I call a non-html format on a class - e.g. json, csv, etc - I get an error
Template is missing
Missing partial /path/to/template with {:locale=>[:en], :formats=>[:json].....
The template is called from a method in the controller.
How can I create a conditional statement in the controller that does something like:
if format is html
my_method_that_causes_the_error
end
Thanks
respond_to do |format|
format.html { my_method_that_causes_the_error }
format.csv { render :something }
end
In your controller
def index # or other method
...
respond_to do |format|
format.html # render index.html.erb
format.json { render json: ...} # one-line block
format.xml do
# multi-line block
end
end
end
Is maybe this what your are looking for?
Typical usage is:
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #users }
end
And now I want to also pass a string named "teststring".
I've seen reference to using
:local => {:users => #users, :another => #another}
But I don't know how to merge the two together. I just haven't seen everything all together. Not much documentation to really explain the :xml in that line. And I don't know if I can deal with the string with :teststring => teststring?
And lastly, how do I deal with them in my index.html.erb now that I have multiple variables? Do they get passed with the same name from the render command?
Thanks.
If you want to render custom XML, you'll need to create a index.xml.erb file in the corresponding view directory for the controller. It works just like any HTML template you'd use, then:
app/controllers/home_controller.rb:
def index
#users = ...
#another = "Hello world!"
# this `respond_to` block isn't necessary in this case -
# Rails will detect the index.xml.erb file and render it
# automatically for requests for XML
respond_to do |format|
format.html # index.html.erb
format.xml # index.xml.erb
end
end
app/views/home/index.xml.erb:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<%= #users.to_xml # serialize the #users variable %>
<extra_string><%= #another %></extra_string>
</document>
(You can read about ActiveRecord's to_xml method here.)
I am experimenting with Rails and was wondering what's needed to allow/add support for JSON requests?
I have a vanilla installation of Rails 2.3.5 and the default scaffolding seem to provide support for HTML & XML requests but not JSON.
class EventsController < ApplicationController
# GET /events
# GET /events.xml
def index
#events = Event.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #events }
end
end
# GET /events/1
# GET /events/1.xml
def show
#event = Event.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #event }
end
end
...
I'm new to this but it would appear as though i would need to add a format line in each method along the lines of:
format.js { render :js => #event.json }
couldn't this be done automatically? perhaps there's a template somewhere i need to update...or a flag i can set? Or perhaps, and most likely, I've missed the boat entirely?!?
You do:
format.json {render :json=>#event}
That will render the default activerecord JSON for the model
The option of ease of use is that you can write a private method which takes the format object and an object to render and then, based on the format, renders different things. Example:
class MyController<ApplicationController
def show
#event=Event.find(params[:id])
respond_to do {|format| myRenderer(format,#event)}
end
...
private
def myRenderer(fmt,obj)
fmt.json {render :json=>obj}
fmt.html
fmt.xml {render :xml=>obj}
end
I want to explicitly call a view from my controller.
Right now I have:
def some_action
.. do something ...
respond_to do |format|
format.xml
end
end
... then it calls my some_action.xml.builder view. How can I call some other view? Is there a parameter in respond_to I'm missing?
Thanks,
JP
You could do something like the following using render:
respond_to do |format|
format.html { render :template => "weblog/show" }
end
See the Rendering section of the ActionController::Base documentation for the different ways you can control what to render.
You can tell Rails to render a specific view (template) like this:
# Renders the template located in [TEMPLATE_ROOT]/weblog/show.r(html|xml) (in Rails, app/views/weblog/show.erb)
render :template => "weblog/show"
# Renders the template with a local variable
render :template => "weblog/show", :locals => {:customer => Customer.new}
Or even simpler since Rails > 3.0:
render "edit"
You can also pass :action, or :controller if that's more convenient.
respond_to do |format|
format.html { render :action => 'show' }
end
You can modify the internal lookup_context of the controller by doing this in your controller
before_filter do
lookup_context.prefixes << 'view_prefix'
end
and the controller will try to load view/view_prefix/show.html when responding to an show request after looking for all the other view prefixes in the list. The default list is typically application and the name of the current controller.
class MagicController
before_filter do
lookup_context.prefixes << 'secondary'
end
def show
# ...
end
end
app.get '/magic/1`
This GET request will look for a view in the following order:
view/application/show.erb
view/magic/show.erb
view/secondary/show.erb
and use the first found view.
Use render
http://api.rubyonrails.com/classes/ActionController/Base.html#M000474