How do I render a partial from the Rails console? - ruby-on-rails

I'm using Rails 4.0.3. How do I render a partial from the Rails console?

Try this (in the console):
# initial setup
view_paths = Rails::Application::Configuration.new(Rails.root).paths["app/views"]
av_helper = ActionView::Base.new view_paths
# (Optional) include this if your partial uses route helpers:
include Rails.application.routes.url_helpers
av_helper.render "path/to/your/partial"
Also, for templates:
av_helper.render :template => "path/to/your/template"
Update: The OP reported the partial rendering line did not work, and generated an error. I didn't encounter that, but if others do, this is the version the OP indicated was successful:
av_helper.render :partial => 'tags/tag', :collection => Tag.limit(3)
As Josh Diehl pointed out, you can also use the usual options like locals in the render. I would expect you should be able to use all the usual render options normally used in controllers and views.
Josh's example:
av_helper.render(partial: "tags/tag", locals: {term: term})

There is an official way to do this in Rails 5 (cf this pull request):
ApplicationController.render 'templates/name'
The developer also made a gem to support this in Rails 4: backport_new_renderer

For me the best way to get it working in Rails 4.2 was with this twoliner:
view = ActionView::Base.new('app/views/products', {}, ActionController::Base.new)
output = view.render(file: 'index.html', locals: {:#products => Product.all})
I found this solution on github.

Related

How to upgrade the :update=>'div_id' option of remote_form_for from Rails 2 to Rails 3?

I can't figure out how to upgrade this code from Rails 2 to Rails 3:
<% remote_form_for(item, :update => 'div_id') do |f| %>
...
I tried this:
<%= form_for :item, :remote => true, :url => { :controller => "items", :action => "create" }, :update => 'div_id' do |f| %>
...
It creates the new item but it fails in updating the content within <div id="div_id"></div> tags. It seems Rails 3 no longer supports the ":update" option for a remote form_for. Any suggestion?
You could use RJS, but that's being deprecated too (and for good reason). The simplified, best-practices way to handle this in Rails 3+ is as follows (assuming jQuery):
# your_view.html.erb
<div id="receiver-id"></div>
<%= form_for :some_model, :remote => true, :id => 'form-id' do |f| %>
...
<% end %>
# application.js (or any other .js loaded on the page)
$(function(){
$('#form-id').bind('ajax:success', function(xhr, data, status){
$('#receiver-id').html(data);
});
});
The ajax:success hook gets called by the jquery-ujs (aka jquery-rails, aka rails-ujs) remote link/form handler. See for yourself. There are lots of other callbacks/hooks available for you to use, too. If you wanted to make this even more flexible, you could use live instead of bind, and bind to a class that dictates where the ouput goes (e.g. "sidebar") and then all remote links/forms with the sidebar class would have their HTML response go to div#sidebar.
The most straightforward way to do this would be to write a javascript view template, e.g. create.js.erb which would look something like this:
$('#div_id').html("<%= escape_javascript(render(#item)) %>");
(depending on your setup, of course, I'm assuming an #item variable and an associated _item partial)
Edit:
coreyward is right. This is the RJS way which is more of the old fashioned Rails 2.x "Rails way". It's probably more familiar, but has issues. Your specific case is one of them, actually, as typically you might bind to an HTML element to update using the record's id (e.g. div #item_1), and in the create case there is no id available beforehand, complicating matters.
Binding via clientside JS eliminates this issue. RJS works in something of a vacuum, making assumptions about the state of the client's HTML and having no access to it.
I know the question is old but I when migrating to Rails 3 I found a pretty good way of doing this, so I thought I would post it here in case anyone else is in a similar solution.
In layouts/update_page.js.erb I put this file:
$j('#<%=#update_div_id||"list_div"%>').html('<%= escape_javascript render(:partial => (#partial_div||"index"), :locals => #local_hash) %>');
This is mainly used for searches that use remote, so in the index action in the controller, I just added the following code.
respond_to do |format|
format.html
format.js {render 'layouts/update_page'}
end
Since remote is being used, it will always try to use javascript first, so it will render the update_page.js.erb file from above. For us, we almost always use the div#list_div on our index pages, so we update that by the default, however if you need to update something different, you can pass in #update_div_id, and if you need to render a different page, you can pass in #partial_div.
To clarify, for a lot of things, it is probably better practice to use the callbacks, but I found this to be a much easier way, when we had to migrate over nearly 100 of these calls.

Rails >= 3.0.8 render inline code with layout not working

It seems the render method has changed.
In the view I used to be able to do the following:
= render :layout => 'some_layout' do
some stuff to be rendered
It seems the best fix is to move the content into a partial and call the layout
= render :partial => 'some stuff to be rendered', :layout => 'some_layout'
I was just wondering if anyone had come across this and if it is a bug or an intended change?
EDIT
Rendering a block inline with a layout works. Check out the part about applying a layout to a block within any template at http://api.rubyonrails.org/classes/ActionView/Partials.html
The issue I am having is with the latest version of HAML not rendering nested render calls properly.
https://github.com/nex3/haml/issues/412
From your post, it appears you are trying to do this in a view.
Is it possible that you are confusing ActionController's render and ActionView's render? Looking # the API documentation for 2.3.8 & 3.x, it doesn't seem there was ever a :layout option within ActionView's render.
UPDATE
Actually, I may have been off-base. It does seem that there is an :inline option as described here.
render(options = {}, locals = {}, &block)
Returns the result of a
render that’s dictated by the options hash. The primary options are:
:partial - See ActionView::Partials.
:update - Calls update_page with the block given.
:file - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
:inline - Renders an inline template similar to how it’s done in the controller.
:text - Renders the text passed in out.
This is fixed in the most recent version of HAML v3.1.3

How to use partial in views with different alias MIME?

Im using 2 different sets of views for 2 different user's roles.
Im using register_alias :
Mime::Type.register_alias "text/html", :basic
in the controller:
class SomeController < ApplicationController
def index
# …
respond_to do |format|
format.html # index.html.erb (advance)
format.basic # index.basic.erb
end
end
end
In some case I have to use the same code in both views, then I would use a Partial, but because of the MIME alias, I have to use 2 identical partials:
my_partial.html.erb and my_partial.basic.erb
I think there is a solution to DRY the code and use only a partial.
Do you have some solutions ?
thank you,
Alessandro
Old Answer:
I probably tried 50 different things until I figured out the right way of writing the partial once, but it was worth it because it's super simple:
Inside your index view, you normally do:
<%= render "my_partial" %>
This implicitly gets mapped to the partial corresponding to the Mime you requested, so it implies having two partial implementations. If you want a DRY partial, simply explicitly specify the format:
<%= render "my_partial.html" %>
As an added bonus of this observation, if your responds_to block of code is really just to switch based on the format and has no logic inside it, you can entirely remove that block of code and things still work implicitly.
Rails 3.2 update:
Rails has deprecated support for the above and support has been completely removed in the latest version of Rails. The following is the correct way as of Rails 3.2:
<%= render :partial => "my_partial", :formats => [:html] %>

How to render a Partial from a Model in Rails 2.3.5

I have a Rails 2.3.5 application and Im trying to render several Partials from within a Model (i know, i know -- im not supposed to). The reason im doing this is im integrating a Comet server (APE) into my Rails app and need to push updates out based on the Model's events (ex. after_create).
I have tried doing this:
ActionView::Base.new(Rails::Configuration.new.view_path).render(:partial => "pages/show", :locals => {:page => self})
Which allows me to render simple partials that don't user helpers, however if I try to user a link_to in my partial, i receive an error stating:
undefined method `url_for' for nil:NilClass
I've made sure that the object being passed into the "project_path(project)" is not nil. I've also tried including:
include ActionView::Helpers::UrlHelper
include ActionController::UrlWriter
in the Module that contains the method that makes the above "render" call.
Does anyone know how to work around this?
Thanks
We use the render_anywhere gem and have been happy with it.
From the README:
require 'render_anywhere'
class AnyClass
include RenderAnwhere
def build_html
html = render :template => 'normal/template/reference',
:layout => 'application'
html
end
end
Including these two modules should be enough. Maybe you forgot to set default_url_options[:host]? Without it you can use _path helpers, but not _url ones.
Include these modules and check out if it works in irb, maybe it will lead you to right solution.

render_to_string in lib class not working

I'm trying to use delayed_job to update a remote database via xml
In my lib folder I put a file with a class that should do a render_to_text with template.xml.builder, but I get:
undefined method `render_to_string' for #<SyncJob:0x7faf4e6c0480>...
What am I doing wrong?
ac = ActionController::Base.new()
ac.render_to_string(:partial => '/path/to/your/template', :locals => {:varable => somevarable})
I had problems with a undefined helper method then I used ApplicationController
ApplicationController.new.render_to_string
render_to_string is defined in ActionController::Base. Since the class/module is defined outside the scope of the Rails controllers the function is not available.
You are going to have to manually render the file. I don't know what you are using for your templates (ERB, Haml, etc.). But you are going to have load the template and parse it yourself.
So if ERB, something like this:
require 'erb'
x = 42
template = ERB.new <<-EOF
The value of x is: <%= x %>
EOF
puts template.result(binding)
You will have to open the template file and send the contents to ERB.new, but that an exercise left for you. Here are the docs for ERB.
That's the general idea.
Rails 5
render_to_string and others are now available as class methods on the controller. So you may do the following with whatever controller you prefer: ApplicationController.render_to_string
I specifically needed to assign a dynamic instance variable for the templates based on an object's class so my example looked like:
ApplicationController.render_to_string(
assigns: { :"#{lowercase_class}" => document_object },
inline: '' # or whatever templates you want to use
)
Great blog post by the developer who made the rails PR: https://evilmartians.com/chronicles/new-feature-in-rails-5-render-views-outside-of-actions
You could turn your template.xml.builder into a partial (_template.xml.builder) and then render it by instantiating an ActionView::Base and calling render
av = ActionView::Base.new(Rails::Configuration.new.view_path)
av.extend ApplicationController.master_helper_module
xml = av.render :partial => 'something/template'
I haven't tried it with xml yet, but it works well with html partials.

Resources