limit partial collection from view - ruby-on-rails

I was trying to limit the rendering of partial collection, but I cannot change the controller or model (don't ask why, it's hard to explaint). So I have to limit it in view and only solution I could come up with is this
def suggested
#suggested ||= current_user.suggested_friends
end
<%= render :partial => 'layouts/three_panel_widgets/friend', :collection => suggested[0..3] %>
do you have any better ideas ?

If you are using rails 3, you can use suggested.limit(4). It will generate a SQL with LIMIT clause. This is a little bit better then using suggested[0..3].
<%= render :partial => 'layouts/three_panel_widgets/friend', :collection => suggested.limit(3) %>

Related

rails render partial not working

this is my simple code
<%= render :partial => '/manage/regions/get_by_country', :locals => {:country_id => #last_search.country_id} %>
the #last_search.country_id has value (checked)
but while rendering the control seems that the country_id is null or empty
what i cant understand is that i use same syntax in another control and work us expected
i try also add hardcoded country_id
<%#id = 118%>
<%= render :partial => 'manage/regions/get_by_country', :locals => {:country_id => #id} %>
<%end%>
and not working
the control rendering but the country_id is null
OK i got the problem
the variable on the partial named #country_id
and i passed country_id (with no the '#')
i actually don't know why in one controller its work and on the other it doesn't work
but when i change the variable on the partial to country_id (with no the '#')
its work as expected
thanks

How to “dynamically add options” to 'form_for'?

I am using Ruby on Rails 3.2.2. In order to implement a "dynamic generated" AJAX style file upload form I would like to "dynamically add options" to the FormHelper#form_for statement if some conditions are meet. That is, at this time I am using code as-like the following (note that I am using the merge method in order to add options to the form_for method):
<%
if #article.is_true? && (#article.is_black? || && #article.is_new?)
form_options = {:multipart => true, :target => "from_target_name"}
else
form_options = {}
end
%>
<%= form_for(#article, :remote => true, :html => {:id => "form_css_id"}.merge(form_options)) do |form| %>
...
<% end %>
However, I think that the above code is too much hijacked.
Is there a better way to accomplish what I am making? For example, can I access from view templates some (unknown to me) instance variable named as-like #form and "work" on that so to change related options as well as I would like? Or, should I state a helper method somewhere? How do you advice to proceed?
BTW: Since the upload process is handled by using a HTML iframe, I am using the remotipart gem in order to implement the AJAX style file upload form - I don't know if this information could help someone...
This looks like a good candidate for a helper method. In your view:
<%= form_for(#article, :remote => true, :html => article_form_options(#article, :id => "form_css_id")) do |form| %>
...
<% end %>
In app/helpers/articles_helper.rb
module ArticlesHelper
def article_form_options(article, defaults = {})
extras = if article.is_true? && (article.is_black? || article.is_new?)
{ :multipart => true, :target => 'form_target_name' }
else
{}
end
defaults.merge(extras)
end
end
Helpers are a good place to keep logic that's too complex for a view but still related to the view.

Rails: confused about syntax for passing locals to partials

Understanding Rails "magic" with regards to rendering partials (and passing locals into them).
Why does this work:
<%= render "rabbits/form" %>
And this work:
<%= render "rabbits/form", :parent => #warren, :flash => flash %>
but this does not work:
<%= render "rabbits/form", :locals => { :parent => #warren, :flash => flash } %>
But this does:
<%= render :partial =>"rabbits/form", :locals => { :parent => #warren, :flash => flash } %>
Also, how can I look up these nuances so I don't need to bother people on S.O.?
The short answer is the render method looks at the first argument you pass in. If you pass in a hash (which includes :partial => 'foo', :locals => {blah blah blah}) then it will pass in all of your arguments as a hash and parse them accordingly.
If you pass in a string as your first argument, it assumes the first argument is your partial name, and will pass the remainder as your locals. However, in that subsequent call, it actually assigns :locals => your_locals_argument, which in this case is the entire :locals => {locals hash}, instead of just {locals hash}; i.e. you end up with :locals => {:locals => {locals hash}}, rather than :locals => {locals hash}.
So my advice is just to always explicitly pass values the same way all the time, and you won't have problems. In order to learn about this, I went directly to the code itself (actionpack/lib/base.rb, render() method in Rails 2; Rails 3 is different). It's a good exercise.
Furthermore, don't worry about "bothering" people on SO. That's why this site exists. I even learned something from this.
if you need to specify :locals, you need to specify :partial or :template
<%= render :partial => "rabbits/form", :locals => {...} %>
should work
To be honost, I only know about these use cases, because I have been keeping up with Rails for the last couple of years and read the announcements that a new way of doing it has been added. I often make a mistake in it myself, but usually it's easily corrected.
It's one of those parts of Rails API that hasn't been thoroughly thought through, if you ask me. It just accumulated more and more syntactic sugar over the years, without deprecating any of the old behavior. The render method has diabetes.
To make it even worse, render behaves differently in controller and view. I also looks at the first argument's content to see if it's a file, template, action or partial. If it starts with a slash then it's a file, or something like that.
I am in favor of using the shorter notation whenever possible. Because the short notations do communicate the intent quite well. When reading it, it usually does what you think it does. Writing partials is not straight forward.
Here is the source of render method from http://api.rubyonrails.org/classes/ActionView/Rendering.html#method-i-render:
def render(options = {}, locals = {}, &block)
case options
# Here is your last case
when Hash
if block_given?
_render_partial(options.merge(:partial => options.delete(:layout)), &block)
elsif options.key?(:partial)
_render_partial(options)
else
template = _determine_template(options)
lookup_context.freeze_formats(template.formats, true)
_render_template(template, options[:layout], options)
end
when :update
update_page(&block)
else
# here the first three cases
_render_partial(:partial => options, :locals => locals)
end
end
Hope this help!

Using sortable_element in Rails on a list generated by a find()

I'm trying to use the scriptaculous helper method sortable_element to implement a drag-and-drop sortable list in my Rails application. While the code for the view looks pretty simple, I'm really not quite sure what to write in the controller to update the "position" column.
Here's what I've got in my view, "_show_related_pgs.erb":
<ul id = "interest_<%=#related_interest.id.to_s%>_siblings_list">
<%= render :partial => "/interests/peer_group_map", :collection => #maps, :as => :related_pg %>
</ul>
<%= sortable_element("interest_"+#related_interest.id.to_s+"_siblings_list", :url => {:action => :resort_related_pgs}, :handle => "drag" ) %>
<br/>
And here's the relevant line from the partial, "interests/peer_group_map.erb"
<li class = "interest_<%=#related_interest.id.to_s%>_siblings_list"
id = "interest_<%=related_pg.interest_id.to_s%>_siblings_list_<%=related_pg.id.to_s%>">
The Scriptaculous UI magic works fine with these, but I am unsure as to how to change the "position" column in the db to reflect this. Should I be passing the collection #maps back to the controller and tell it to iterate through that and increment/decrement the attribute "position" in each? If so, how can I tell which item was moved up, and which down? I couldn't find anything specific using Chrome dev-tools in the generated html.
After each reordering, I also need to re-render the collection #maps since the position is being printed out next to the name of each interest (I'm using it as the "handle" specified in my call to sortable_element() above) - though this should be trivial.
Any thoughts?
Thanks,
-e
I typically create a sort action in my controller that looks like this:
def sort
order = params[:my_ordered_set]
MyModel.order(order)
render :nothing => true
end
Don't forget to add a route:
map.resources :my_model, :collection => { :sort => :put }
Now, on MyModel I add a class method that updates all of the sorted records with one query (this only works in mysql, I think..):
def self.order(ids)
update_all(
['ordinal = FIND_IN_SET(id, ?)', ids.join(',')],
{ :id => ids }
)
end
The single query method comes from Henrik Nyh.

Displaying Data in form after using activerecord

I have a form that the user is going to interact with, by updating, etc. The data is being pulled from the database, so that the user can see previous data and add new ones as well. So basically when I try to execute the code below, I get an error, saying that there is no method...
#display = Sales.find(:all, :conditions => ['year =?', _year])
render :partial => "display" #which renders the table that has the form in it.
<td><%= text_field 'display', 'price'%></td> #is the input field
I have price as a column in my database :S
Thanks for the help guys! Merry X-mas
The display variable is an Array. You'll need to pass the results of the Sales.find in the :collection parameter of render partial:
#display = Sales.find(:all, :conditions => ['year =?', _year])
render :partial => "display", :collection => #display
That should render the partial once for each item that is returned by Sales.find

Resources