render :inline => "<%= yield %>" not working - ruby-on-rails-3

I'm upgrading from Rails 2.3.8 to 3.0.3 and notice that my code for nested layouts isn't working.
In my main Application layout I have the line
<%= controller.sub_layout %>
which then looks to the controller, who has:
def sub_layout
render :inline => "<%= yield %>"
# or otherwise some partial for the sub-layout
end
The problem is, this doesn't get rendered! If I put a direct <%= yield %> statement in the layout, it does work. So the question is, what's happening here, and how do I fix it?
This worked beautifully in Rails 2.3.8

How about a much saner approach:
render :layout => false
Related: http://guides.rubyonrails.org/layouts_and_rendering.html#using-render

So you all have some more of a background on this, the whole sub-layout approach was based on this blog post: Sorta Nested Layouts (The solution is given in the comments section.)
Instead of making a controller method sub_layout, any controller that uses a sublayout needs to define a before_filter method that sets a variable:
def inner_layout
#inner_layout = 'layouts/sublayout_partial_name'
end
then in the main layout.html.erb (i.e. application.html.erb), where you would otherwise put your yield statement:
<%= #inner_layout ? render(:partial => "#{#inner_layout}") : yield %>
the assumtion is that the sublayout partial file will have its own yield statement in there somewhere.

Related

link_to Helper Modifications

Inside of a rails app that I am working, I modified the link_to helper slightly:
def link_to(*args, &block)
args[1] = params[:client_id].present? ? "#{args[1]}?client_id=#{params[:client_id]}" : args[1]
super
end
I did this so I wouldn't have to add the :client_id => params[:client_id] every time I wrote a link_to inside of the app. Well, I have kind of pigeon holed myself with the following problem...
If I have this link_to:
<%= link_to "Continue to billing info", add_product_path(:product_id => #product.id), :class => 'btn' %>
Using my link_to helper creates a link, like so:
http://localhost:3001/orders/add_product?product_id=35?client_id=HT274848772
I am at a slight loss on how to modify my helper so that the link will work as normal while including the :client_id param...
You want to add your parameter to the link url, not to the link itself. Maybe you should rewrite the url_for helper, which is the helper used by all of the url helpers ( http://apidock.com/rails/ActionView/Helpers/UrlHelper/url_for )

customize kaminari pagination template

I'm having difficulty customizing the default kaminari template.
I've used the generator to create kaminari template files. In kaminari/paginator.html.haml:
= paginator.render do
%nav.pagination
All I want to do is access the actionview helpers within this, like link_to, or render. I've searched the source code and I can't find any incline of the helper being passed to this render method.
Essentially, being able to do this:
= paginator.render do
%nav.pagination
= render :partial => 'custom links'
= link_to "custom link", custom_path
..would solve my problems.
I didn't get a satisfactory answer, and so I'll submit my own solution.
Helpers cannot be used in the paginator.render block.
So, first I generate kaminari custom template files:
rails g kaminari:views default -e haml
Create a new file kaminari/custom.html.haml with the contents:
#pagination
= paginate custom
= render :partial => "kaminari/custom_view_file"
Replace kaminari paginator helper (paginate #results) in your view file with:
= render :partial => "kaminari/custom", :object => #results
You should be able to do something like this:
# /app/views/kaminari/_paginator.html.erb
= paginator.render do
%nav.pagination
= render :partial => 'shared/custom'
= link_to "custom link", custom_path
Basically, you need to provide the full path of the partial as it probably does not reside in the same directory.
EDIT:
I think Kaminari does not import rails view helpers in the paginate.render block in _paginator.html.erb.
To customize the output generated by paginator, you should instead
1. customize the _next_page.erb.html and so on where you can use rails helpers. I don't know why it is so though.
2. If you want to display some common html as a part of paginator, I suggest you put it in layout instead. Paginator is about navigation of pages.
For example, this is the _prev_page.html.erb:
<span class="prev">
<%= link_to "google", "www.google.com" %>
<%# link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote %>
</span>
I just commented out the old code and used a custom link.
Just met the same problem.
My solution:
= paginator.render do
%nav.pagination
= render :partial => 'custom links'
= #template.link_to "custom link", custom_path
As partial rendering occurs in scope of Paginator, there is possibility to use its instance variable, pointing to template (see https://github.com/amatsuda/kaminari/blob/master/lib/kaminari/helpers/paginator.rb)
Little hacky, but works.

Format.js will only render a partial that contains a single line

Rails 3.2.1: I have the following div that calls a partial
<div id="weighin">
<%= render :partial => "my_weight/weighin" %>
</div>
The partial contains a form that posts ajax (ie has :remote => true) to a controller with:
respond_to do |format|
format.js
end
The .js.erb file has a single line:
$("#weighin").html("<%= render :partial => "my_weight/weighin1" %>");
The _weighin1.html.erb partial file has a single line:
<p><%= #my_weight[1].weight %></p>
This works, in that the original div is replaced with the value of the #my_weight field - so the fundamental structure is all working ok
However, Rails will not handle any more code in the partial - if I add so much as a carriage return to the end of that one line, the server log confirms all ok, but no script gets run on the page - ie nothing changes.
The same happens if I try to put more html in the partial, but put it all in a single line - this doesnt run either.
How can I output more than a single short statement in a partial?
OK, I figured this out:
$("#weighin").html("<%= escape_javascript(render :partial => "my_weight/weighin1") %>");
escape_javascript is essential
What is confusing is that, depending on what is in the html() you are sending, this will sometimes work without escape_javascript, leading one to a false conclusion... :-)

Rendered partial not receiving params

I'm trying to implement an 'edit' link that brings up a form to change a displayed attribute on a page.
My layout has:
<div id="company_info">
<%= yield :company_info %>
</div>
<div id="edit_company_info">
</div>
My view has:
<%= content_for :company_info do %>
<%= render 'company_info' %>
<%= link_to "Edit", 'company_info_form', :class => 'btn btn-mini', :method => :get, :remote => true %>
My controller has:
def company_info_form
#company = Company.get(params[:id])
respond_to do |format|
format.js
end
end
My company_info_form.js.erb file has:
$('#edit_company_info').html("<%= escape_javascript(render "company_info_form") %>");
Upon clicking the link, my server shows:
Started GET "/companies/company_info_form" for 127.0.0.1 at 2012-03-12 20:19:13 -0700
Processing by CompaniesController#show as JS
Parameters: {"id"=>"company_info_form"}
Completed 500 Internal Server Error in 1ms
RuntimeError (Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id):
app/controllers/companies_controller.rb:9:in `show'
So I think this is a routing issue-- but I have no idea how to fix it. How do I get the company_id param that is on my current page to be recognized by the partial I'm loading as well?
I'm on /companies/1, but the link is to companies/company_info_form, losing the "company_id = 1" param.
Yes, the issue is with your routes and with your link as you have pointed out.
The first issue can be ascertained as it says Processing by CompaniesController#show as JS. So, its actually going to companies#show where it tries to find a company based on id. But, since no correct id is passed, it errors out.
The second issue is because your link is to companies/company_info_form, as you pointed out, since you have used 'company_info_form' as the path in your link for edit. And you haven't passed current company to the link either.
Since you haven't posted your routes file, which you should have, since you have identified a potential problem with routes , I'll present my own.
In your routes :
resources :companies do
member do
get 'company_info_form'
end
end
That will provide you with
company_info_form_company GET /companies/:id/company_info_form(.:format) companies#company_info_form
Then you can provide the link as :
<%= link_to "Edit", company_info_form_company_path(#company) %>

Is view_context no longer available in Rails 3 views?

in a current Rails 3.0.9 app of mine I had a few .js.erb templates that were using view_context in them so I could call fields_for on it during a ajax request. This was letting me build some nested attribute form fields via ajax. But upon upgrading to Rails 3.1 I'm getting the follow error:
ActionView::Template::Error (undefined local variable or method `view_context' for #<#:0x1057b9f70>):
Was this removed/deprecated recently? Is there another way I can build nested fields_for inputs without having the parent FormBuilder handy? It seems view_context is still available in the controller, but I was hoping to keep this markup generation in the View layer.
My .js.erb template looked like this
<% meal_item_fields = view_context.fields_for :meal_items, Meal.new.meal_items.new, :child_index => "new_meal_items" do |f|
render :partial => 'meal_items/meal_item_fields', :locals => {:meal_item_form => f}
end
%>
$("#meal-items").append("<%= escape_javascript(meal_item_fields) %>");
According to api docs it is deprecated in >= 3. Source of 3.0.9 returned self for view_context. I think if you were to try without view_context it would just work.
<% meal_item_fields = fields_for :meal_items, Meal.new.meal_items.new, :child_index => "new_meal_items" do |f|
render :partial => 'meal_items/meal_item_fields', :locals => {:meal_item_form => f}
end %>
$("#meal-items").append("<%= escape_javascript(meal_item_fields) %>");
You might want to add helper_method :view_context in your controller.