Rendering just html with Rabl - ruby-on-rails

I'm trying to figure out how to render just html with Rabl. I have an html partial without an object, so far all I can see are examples of partials with objects. If I try it without the object it just (obviously) throws an error.
The closest I got was:
node(:content) do
partial("api/v1/api/partials/tips")
end
Here is the documentation for Rabl.
UPDATE
I ended up just going with this below. Obvious right? For some reason when I tried it the first time it didn't work. So for sending only HTML in API responses, this works well.
def tips
render partial: "api/v1/api/partials/tips"
end

in a rabl view, for example show.v1.rabl you're able to render a view partial with the following (rails 4.1.2):
object #your_object
code :html do
context_scope.controller.render_to_string(
# from app/views/
partial: 'path/to/show.html.erb',
# locals (if needed)
locals: {
your_object: #your_object
}
)
end

This can be achieved by rendering an ERB template inside the Rabl node:
object #user
node(:html_content) do |user|
#user = user
template = Rails.root.to_s + '/app/views/api/users/show.html.erb'
ERB.new(File.read(template)).result(self.binding)
end

Related

Rails/Ajax/Error Processing

So there are tons of articles about how to do this, but certainly there's a best practice...and I don't know enough to filter out silly solutions, good ones, and best ones.
I simply want to submit my forms via ajax (in a dialog) and get the errors back just like I would without using ajax...meaning I like the rails standard error handeling/flash messages/label classes.
Is the best way to reload the entire partial?
Is the best way to use .js.erb (or coffee) for partial stuff? (If so, can you explain how to use these partials?
Is the best way to parse JSON back into the form somehow?
What else am I missing in my [limited] knowledge base?
The way I'd do it is to render a create.js.erb view like:
$("#my_dialog").replaceWith("<%= j(render 'dialog') %>");
where _dialog.html.erb contains the HTML for the contents of your dialog.
<div id="my_dialog">
<!-- flash stuff etc -->
<%= form_for ... %>
<!-- ... -->
<% end %>
</div>
Your controller, for example, will look something like:
class EntriesController < ApplicationController
def create
#entry = Entry.new(params[:entry])
respond_to do |format|
if #entry.save
format.html { redirect_to #entry }
format.js {} # this will render create.js.erb for js requests
else
format.html { render action: "new" }
format.js {} # this will render create.js.erb for js requests
end
end
end
end
summit like 'dat. If you don't want to reload the whole form you can update or do whatever you want in .js.erb
Using js.erb is the way to go. Here's the rationale:
Reloading part of your page basically defeats the purpose of Ajax - which is to modify the page without having to reload or refresh anything. And parsing JSON would be quite tedious.
Using js.erb lets you easily leverage validations that Rails provides. In your js.erb, you can access anything that you normally would from your controller, including the validation errors, you and you can update DOM elements based on those errors. Since you're modifying individual DOM elements, you don't need to concern yourself over the fact that your form may be inside a partial.

render partial of another namespace

I have a problem. I need to render objects using partials of another namespace.
render complain.target
it tryes to render partial from current namespace(current is admin)
Missing partial admin/bulletins/bulletin...
I dont need to render it from admin/..
I cant specify partial path like
render partial: '/bulletins/bulletin', locals: { bulletin: complain.target }
But it's polymorphic association, and different partial pathes are used.
Is it any way to do it?
Thanks in advance!
There seems to be no possible way to achieve this with a render complain.target call (Checked on Rails 5 source).
There is a config option for action_view to disable namespace prepending for partials, though:
Rails.application.config.action_view.prefix_partial_path_with_controller_namespace = false
EDIT
Today, I've used another solution:
When rendering Single-Table-Inheritance models into partials, one can pass the locals variable name based on the Rails model_name lookup, when calling the render partial:
<%= render partial: "admin/#{object.to_partial_path}",
locals: { object.model_name.element => object }
%>
You can use render "/#{complain.target.to_partial_path}"

Rails render subaction gem

Here is my problem with Rails.
Sometimes there is independent blocks at the page (e.g. "Latest news") which has no logical relation to current controller or action. In regular rails MVC stack I would write #news = News.latest in my controller and render 'shared/latest_news', news: #news in my view.
However its too much for me for several reasons. Instead I want to write render 'shared/latest_news', locals_call: "NewsController#latest" in view and that's it.
What should happen behind this row is calling "NewsController#latest" method to receive a hash of locals used in rendering this template.
Does anyone know gem for such calls?
You could make a universal helper method in ApplicationHelper:
def latest_news_tag
render partial: 'shared/latest_news', locals: { news: News.latest }
end
You can call this method in any view you want, e.g. <%= latest_news_tag %>.

Is there an easy way to use a JSON layout in Rails 3.1 for `render json: {}`?

Is it possible to specify a layout for rendering JSON in Rails 3.1+ (not that I found any easy way to do it in any previous version of Rails)?
I've been using a helper like this:
def render_as_json(obj, status = 200, *args)
render(inline: obj.to_json(*args), layout: 'default', status: status)
end
It doesn't seem like render json: obj will render a layout.
I just wanted to have some metadata in the layout file:
<%- #content = yield -%>
{
"data":<%= #content.present? ? raw(#content) : '{}' %>,
"metadata":<%= raw(json_layout_metadata.to_json) %>
}
I know this is old now but I was trying to use a JSON layout and an XML layout and while searching I found your question and it helped me somehow solve my problem so here is what I did for the JSON part and the XML is pretty much the same:
Create a template file in the layout folder in your application(in the same directory of application.html.erb), call it anything but make its extension ".json.erb", let's assume you named it "json_layout.json.erb". Put in it whatever constant content you want to add and in the place you want to display dynamic data put a
<%= yield %>
In my case, this is my template:
{"status": <%= response.status %>,"data": <%= yield %>}
Now in your controller where you want to display JSON use the following format in the respond_to block:
format.json { render :inline => #the_object.to_json(any_additional_options) , :layout => "json_layout.json.erb" }
Just be careful in case of XML to put in the options of the to_xml method
:skip_instruct => true
as you would probably don't need the full XML generated by default because you add your own in the layout.

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] %>

Resources