How can I make this sophistictaed? - ruby-on-rails

I'm trying to change this pagination to reverse pagination. from
|Last|Next|25|24|23|22|21|Previous|First|
to
|First|Previous|21|22|23|24|25|Next|Last|
So, I coded like this below, but it takes so long. It's probably because it fetches all the comments in order to pass argument first, and then it does again in application_controller.rb
Is there any smart way to make this faster?
user_controller.rb
#comments = reverse_paginate(Comment.where(:user_id => user_ids, :commentable_type => commentable).order('created_at DESC'), params[:page])
application_controller.rb
def reverse_paginate(scope, page)
if page
page_number = page
else
page_number = Kaminari.paginate_array(scope.reverse).page(1).per(10).num_pages
end
Kaminari.paginate_array(scope.reverse).page(page_number).per(10).reverse!
end

I think you'll have to override the paginator template of Kaminari.
<%= paginator.render do -%>
<nav class="pagination">
<%= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>
<% each_page do |page| -%>
<% if page.left_outer? || page.right_outer? || page.inside_window? -%>
<%= page_tag page %>
<% elsif !page.was_truncated? -%>
<%= gap_tag %>
<% end -%>
<% end -%>
<%= next_page_tag unless current_page.last? %>
<%= last_page_tag unless current_page.last? %>
</nav>
<% end -%>
Source here

Related

DRY ruby on rails loops

I am trying to loop through my users and sum an attribute act_points from associated post_activites and then assign and save it to my users table attribute total_points. The code below works for me but it doesn't follow DRY.
<% #users.order("total_points desc").each do |u| %>
<p><% u.total_points = u.post_activities.sum(:act_points).round(2) %> </p>
<% u.total_points %>
<% u.save %>
<%end%>
<% #users.order("total_points desc").each do |u| %>
<p><% u.total_points = u.post_activities.sum(:act_points).round(2) %> </p>
<%= u.total_points %>
<%end%>
Any suggestions on how to combine these loops or shorten them?
You can refactore your code in this way:
# user.rb
def actual_points
post_activities.sum(:act_points).round(2)
end
def update_total_points
update(total_points: actual_points)
end
# in controller (change index to your method)
def index
#users = User.order("total_points desc")
#users.find_each do |user|
user.update_total_points
end
end
# view
<% #users.each do |u| %>
<%= u.total_points %>
<%end%>

Check if Spree Cart is empty

How can I check if the Spree cart is empty, so I can change the button if it isn't?
I thought there was a method line_items.count...
<% unless line_items.count > 0 %>
<%= link_to "<button>Empezar Pedido</button>".html_safe, "/shop" %>
<% else %>
<%= link_to "<button>Terminar Pedido</button>".html_safe, "/shop" %>
<% end %>
Thanks!
This is very simple I solved my this problem like this
In application_controller.rb
def load_cart
#order = current_order
end
In frontend in you case
<% unless #order.line_items.count > 0 %>
<%= link_to "<button>Empezar Pedido</button>".html_safe, "/shop" %>
<% else %>
<%= link_to "<button>Terminar Pedido</button>".html_safe, "/shop" %>
<% end %>
Thanks

TypeError: can't convert Symbol into Integer

I get a "TypeError in Activities#member - can't convert Symbol into Integer"
I would say that 95% of my records work fine but I have a couple that keep tripping this error. Where do I start to look at this problem.
Here is the code I am working with:
.html.erb page
<div id="listing-gallery">
<ul id="listing-slides">
<% listing.slides.each_with_index do |slide, i| %>
<%= content_tag :li, :id => "slide#{i}", :class => (i == 0) ? "active" : "" do %>
<%= image_tag slide[:large] %>
<% end %>
<% end %>
</ul>
<ul id="listing-slide-thumbs">
<% if listing.slides.count > 1 %>
<% listing.slides.each_with_index do |slide, i| %>
<%= content_tag :li, :class => (((i+1)%4 == 0) ? "last" : "") do %>
<%= content_tag :a, :href => "#slide#{i}" do %>
<span class="hover"></span>
<%= image_tag slide[:thumb] %>
<% end %>
<% end %>
<% end %>
<% end %>
</ul>
.activities_controller.rb
def member
# Assign attrs if venue exists
if #member.nil? || #member.venue.nil?
redirect_to activities_path
else
if #member.venue.attrs.count > 0
# match_by_type can be found in the ApplicationHelper
#attrs = match_by_type #member.venue.attrs
else
#attrs = nil
end
unless #member.venue.nil?
unless #member.venue.attrs.nil?
#member_rentals = #member.venue.attrs.all_by_type("Rentals")
end
end
end
end
Where do I go from here?
see <%= image_tag slide[:large] %> and <%= image_tag slide[:thumb] %>
what image attribute for slide?
If image is attribute for slide, I think such as :
<%= image_tag slide.image.url(:large) %>
or if usinng carrierwave
<%= image_tag slide.image_url(:large).to_s %>
By the way, I don't see listing.slides on action member

Rails element if first time appearance

I have a model Post with :mark, :text
I have a list with my post
<% #posts.each do |p| %>
# todo
<% if p.mark? %>
<%= p.mark %> <%= sweet_thing(p.text) %>
<% else %>
<%= sweet_thing(p.text) %>
<% end %>
<% end %>
I need to show p.mark name instead #todo where p.mark first time appearance.
Final txt example:
Audi
Audi, text-text-text-text.
Audi, text-text-text-text.
Audi, text-text-text-text.
Ford
Ford, text-text-text-text.
Ford, text-text-text-text.
Ford, text-text-text-text.
Ford, text-text-text-text.
UPDATE
My txt render in controller
def txt_receiver
#posts = Post.where("created_at >= ?", 7.days.ago.utc).find(:all, order: "mark, LOWER(post)")
render "txt_for_newspapper", formats: ["text"]
end
An obvious solution is to keep track of seen marks.
<% seen_marks = {} %>
<% #posts.each do |p| %>
<% unless seen_marks[p.mark] %>
<%= p.mark %>
<% seen_marks[p.mark] = true %>
<% end %>
# rest of your code
<% end %>
A better solution (I think) involves grouping posts by their mark and then outputting in groups. But I'm not sure whether it will match your logic regarding missing marks.
<% #posts.group_by(&:mark).each do |mark, posts| %>
<%= mark %>
<% posts.each do |p| %>
<%= p.mark if mark %> <%= sweet_thing(p.text) %>
<% end %>
<% end %>

Conditional tag wrapping in Rails / ERB

What would be the most readable and/or concise way to write this in ERB? Writing my own method isn't preferable, as I would like to spread a cleaner solution for this to others in my company.
<% #items.each do |item| %>
<% if item.isolated? %>
<div class="isolated">
<% end %>
<%= item.name.pluralize %> <%# you can't win with indentation %>
<% if item.isolated? %>
</div>
<% end %>
<% end %>
== Update ==
I used a more generic version of Gal's answer that is tag agnostic.
def conditional_wrapper(condition=true, options={}, &block)
options[:tag] ||= :div
if condition == true
concat content_tag(options[:tag], capture(&block), options.delete_if{|k,v| k == :tag})
else
concat capture(&block)
end
end
== Usage
<% #items.each do |item| %>
<% conditional_wrapper(item.isolated?, :class => "isolated") do %>
<%= item.name.pluralize %>
<% end %>
<% end %>
If you really want the DIV to be conditional, you could do something like this:
put this in application_helper.rb
def conditional_div(options={}, &block)
if options.delete(:show_div)
concat content_tag(:div, capture(&block), options)
else
concat capture(&block)
end
end
which then you can use like this in your view:
<% #items.each do |item| %>
<% conditional_div(:show_div => item.isolated?, :class => 'isolated') do %>
<%= item.name.pluralize %>
<% end %>
<% end %>
Try:
<% #items.each do |item| %>
<div class="<%= item.isolated? 'isolated' : '' %>">
<%= item.name.pluralize %>
</div>
<% end %>
I like PreciousBodilyFluids' answer, but it doesn't strictly do exactly what your existing method does. If you really cannot have a wrapping div, this may be prefereable:
<% #items.each do |item| %>
<% if item.isolated? %>
<div class="isolated">
<%= item.name.pluralize %>
</div>
<% else %>
<%= item.name.pluralize %>
<% end %>
<% end %>
A helper method to do all of this would probably look like this:
def pluralized_name_for(item)
if item.isolated?
content_tag(:div, item.name.pluralize, :class => 'isolated')
else
item.name.pluralize
end
end
Then your view code would look like this:
<% #items.each do |item| %>
<%= pluralized_name_for(item) %>
<% end %>

Resources