Using scope with a view partial - ruby-on-rails

I have been using a scope to present some information to show todos that have been completed and are 24 hours old
scope :completed, joins(:user).where(:todos => { :complete => true })
scope :logged, completed.where("todos.updated_at <= ?", 1.day.ago)
Using the regular todo partial
<%= render #user.todos.logged =>
However I want to present those logged items in a different partial _logged.html.erb. I just can't figure out the proper way to pass scope results to a specific partial.
Thanks

Well, if you want to render partial for each item, yo can do:
<%=render :partial=> 'logged', :collection=>#user.todos.logged %>
Or if you want to pass the whole array to one instance then you can do
<%=render :partial=> 'logged', :object=>#user.todos.logged %>
In both cases I guess your object will be called logged.
Assuming that your partial contains <%= logged.title %> you want to render for each item, so you can use the first version.

First, to keep my conscience clean, let me say that that passing model code to your views is never a good idea. But if you insist :
<%= render :partial => 'some_partial',
:locals => {:some_variable => "somevalue",
:some_other_variable => some_other_variable} %>

Related

How do I pass a variable into this partial to use as a counter?

<div class="postSlideshowDots">
<%for i in #post.images%>
<%=render :partial => "dots", :locals => {:image => i }%>
<%end%>
</div>
I would like to also pass in a variable (=0 when it goes in) to use as a counter. I had read that there was one already built in, "partialname_counter", but that gave me an error.
use <%= render :partial => "dots", :collection => #post.images %>, and you will get a variable called dots_counter in the partial. You will also need to change your partial to use dots instead of image as the variable.
Finally, don't use for..in in Ruby, it is non-idiomatic, and has some bad behavior in regards to closures and scoping. Use .each

Pass Parameters in render - Rails 3

I've seen a couple questions on this but haven't been able to solve it...
I'm trying to pass a parameter while rendering a partial (similar to domainname.com/memory_books/new?fbookupload=yes)
Right now, I use this line:
<%= render :partial => '/memory_books/new', :fbookupload => "yes" %>
and in the partial, I have tried to get the content of fbookupload by using:
<%= fbookupload %>
which gives an "undefined local variable" error and
<%= params.inspect %>
which does not show fbookupload as a parameter.
How can I have the partial pass along the parameter :fbookupload?
Thank you.
UPDATE:
Could it have anything to do with the fact that I'm rendering this within a render?
i.e. the page (/fbookphotos/show) that has
<%= render :partial => '/memory_books/new', :fbookupload => "yes" %>
is being rendered by another page with (posts/show) via:
<%= render :partial => '/fbookphotos/show' %>
so I'm rendering this within a render.
try this:
<%= render :partial => '/memory_books/new', :locals => {:fbookupload => "yes"} %>
Taking it out of the comments for posterity. This syntax is correct:
render '/memory_books/new', fbookupload: "yes"
But if there is a reference to rendering the same partial without specifying the local variables, e.g.
render '/memory_books/new'
then fbookupload variable becomes unavailable. The same applies to multiple local variables, e.g.
render 'my_partial', var1: 'qq', var2: 'qqq'
will work if only occurs once. But if there is something like that somewhere else in the code
render 'my_partial', var1: 'qq'
then the var2 will become unavailable. Go figure ...
To do it your way:
In the main view:
<% fbookupload = "yes" %>
<%= render :partial => '/memory_books/new', :locals => {:fbookupload => fbookupload} %>
And in the partial:
<%= fbookupload %>
2nd option:
Ideally in the controller, otherwise in the view, define an instance variable: #fbookupload = "yes". Then it is available everywhere. The partial will then be : <%= #fbookupload %>
Params is just request parameter, so if u want to pass it in params u have to add it to your url ?fbookupload=yes or assign it params[:fbookupload] = "yes", but i don't think that is a good idea.
But if u need to use params[:fbookupload]', u can replace it withparams[:fbookupload] || fbookupload', and pass fbookupload in locals hash for partial.
render can be called with or without the partial param, and there seems to be some confusion around the differences between these two forms.
The following two are equivalent:
<%= render "my_partial', my_param: true %>
and:
<%= render partial: "my_partial', locals: { my_param: true } %>
The first is a shorthand that allows you to omit partial:. With this shorthand, local variables are also not nested under locals:. This is explained well in the documentation (see 'Rendering the default case').
In the two cases above, you would access my_param in the partial directly with my_param.
One other source of confusion is that if you render the partial somewhere without passing my_param, then the partial will fail when it tries to access it. To get around this, you can access the local with local_assigns[:my_param] instead of my_param, which will give you nil if the param is not defined instead of erroring, as described in this documentation. Another alternative is to use defined?(my_param) before accessing it.

Rails partial collection empty?

I've been trying to figure this one out for about an hour now. I have a partial collection that is indeed populated with member model objects, and when I try to render it using collection:
<%= render :partial => 'list', :collection => #members %>
In my _list.html.erb the #member_id and #member_email attributes are empty in the rendered html:
<%= check_box_tag('selected_member[]', #member_id, false) %>
<%= #member_email %>
The view renders correctly and I get 3 member items, but with the id and email blank.
What am I doing wrong? If I try to access the partial member using "member_id" or "member.id" I get "undefined local variable or method `member'", so clearly that's not the correct notation.
Now I've seen a bunch of different examples, but the collection method is the way I need to go. I need the partial to only deal with each member as the parent view has support for grouping members in different ways. If I implement a loop in the partial for each member, I'll have to move the grouping view code into it as well, which interacts with input fields in the parent view. e.g. it would be a mess to maintain.
Thanks in advance.
When you do:
<%= render :partial => 'list', :collection => #members %>
Rails is expecting the local variable within the partial file to be named the same as the partial file itself, in this case list.
So instead of member, by default it would be list like this:
<%= check_box_tag('selected_member[]', list.id, false) %>
<%= list.email %>
If you want the local variable to instead be named member, you should either rename the partial file or use this syntax:
<%= render :partial => 'list', :collection => #members, :as => :member %>
More info here (Sec. 3.4.5): http://guides.rubyonrails.org/layouts_and_rendering.html

Rails: Rendering a partial to the right div?

I have a loop in my view that renders many partials: each partial is a simple toggle to perform a save/unsave operation on a record. Each partial toggles the boolean field using javascript then updates itself, and the controller finishes by saying:
$ controller
render :partial => "save_unsave_buttons", :locals => {:matching => #matching}, :layout => false
# view
<div id=<%= "save#{match.id}" -%>>
<%= render :partial => "save_unsave_buttons", :locals => {:matching => match} %>
</div>
When the controller renders the save_unsave_buttons partial, it isn't rendering to the right div; it just updates the partial for the first record it finds. How can I ask the controller to render the save_unsave_buttons partial to the div with the right id?
Thanks!
Looking at only the little info that you provided for your problem i guess the culprit in the code is the div tag.
The div tag should be within the partial.
EDIT: What your code does is it creates a single div with id save(the first match.id) and renders the partial within it. If I understood you correctly you need a div for each match. For that the div itself should be within the partial.
So pass the match.id to the partial in a collection. Your view should be:
# view
<%= render :partial => "save_unsave_buttons", :locals => {:matching => match, :collection => {#match_id => match.id} } %>
and in your partial _sav_unsave_buttons.html.erb:
<% content_tag :div, id => "save#{#match_id}" do %>
#YOUR CODE GOES HERE!
<% end -%>

Rails AJAX: My partial needs a FormBuilder instance

So I've got a form in my Rails app which uses a custom FormBuilder to give me some custom field tags
<% form_for :staff_member, #staff_member, :builder => MyFormBuilder do |f| %>
[...]
<%= render :partial => "staff_members/forms/personal_details", :locals => {:f => f, :skill_groups => #skill_groups, :staff_member => #staff_member} %>
[...]
<% end %>
Now, this partial is in an area of the form which gets replaces by an AJAX callback. What I end up doing from the controller in response to the AJAX request is:
render :partial => "staff_members/forms/personal_details", :locals => {:skill_groups => #skill_groups, :staff_member => #staff_member}
However, if I do that then the form breaks, as the FormBuilder object I used in the form_for is no longer available. Is there any way for me to use my custom FormBuilder object inside a partial used for an AJAX callback?
Use fields_for inside your partial. It performs a similar task but without wrapping the form tags. See the API docs.
how about this?
#template.with_output_buffer do
#template.form_for #model_object do |f|
f.fields_for :some_nested_attributes do |ff|
render :partial => 'nested_attributes', :object => #model_object, :locals => {:form => ff}
end
end
end
this would be especially useful is you need to use the nested fields_for in the partial
You could instantiate a new instance of your form builder in the controller, though it feels sort of lousy to me:
# in the controller
render :partial => {
:f => MyFormBuilder.new(:staff_member, #staff_member, template),
:skill_groups => #skill_groups,
:staff_member => #staff_member
}
Alternatively, you could move more of the update logic to be client side which wouldn't require you to worry about rendering anything at all. You could just update the values via JS. Not sure if that works for your project though.
Maybe I'm a little late in the game here, and maybe I don't understand the question properly, but in ApplicationHelper.rb I think you can just add the line:
ActionView::Base.default_form_builder = MyFormBuilder
You can submit within your ajax call the content of f.object_name (it's also works with partials) and use it to render tags defined in http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html passing it as the first argument.

Resources