reverse order of publications grouped by year - ruby-on-rails

For archiving the publications in my Rails app, I group the publications by year:
app/controllers/publications_controller.rb
...
def series
#publications = Publication.all
#publications_year = #publications.group_by { |p| p.year}
end
then in the view, I want to have a link for each publication year:
<% #publications_year.sort.each do |year, pubs| %>
<li><i class="fa fa-folder left"></i><%= link_to year, archive_path(year) %></a>
</li>
<% end %>
this works fine, the result is:
2012
2013
2014
However, I need to reverse the order, so the links should be ordered like this:
2014
2013
2012
...
But I can't figure out how to this
Does anyone know how I can reverse the order of the year links?
thanks for your help,
Anthony

You can also let the db do the ordering.
#publications_year = #publications.order('year DESC').group_by { |p| p.year }
If you do it this way, you don't need to call sort anymore.

did you try using the reverse method?
#publications_year.sort.reverse.each
source: http://apidock.com/ruby/Array/reverse

Related

Rails 5.1, group_by, parse date, i18n

I have a very specific problem to get the month name in I18n. I'm grouping some infos per month and year, and it looks like that when I want to translate it, all the month with a specific caracter like é or û aren't working, where the rest is. Let me show you how it looks like :
Helper :
def user_spendings_paginate
user.spendings.all.order('date DESC').paginate(:page => params[:page], :per_page => 15)
end
def grouped_spendings
user_spendings_paginate.group_by{ |t| t.date.to_date == DateTime.now.to_date }
end
def month_wise_sorted_spendings
if user_spendings_paginate.present?
user_spendings_paginate.group_by{ |t| t("date.month_names")[t.date.month] + " " + t.date.year.to_s }
end
end
So as you can see, I call all the user.spendings. I group them twice, the first to get the date of the day and the other to get the rest per month and year. As you can see I i18n the month name. In my yml file I have that :
month_names:
-
- Janvier
- Février
- Mars
- Avril
- Mai
- Juin
- Juillet
- Aout
- Septembre
- Octobre
- Novembre
- Decembre
I tried to remove the é from Décembre and the û from Août to try, but the problem remains the same.
My controller :
if params[:month]
#date = Date.parse("#{params[:month]}")
else
flash[:error] = t(".something_wrong")
redirect_to myspendings_path(locale: I18n.locale)
end
And my view :
<% date_in_link = " #{month}" %>
<p><%= link_to myspendingsdetail_path(:month => month, locale: I18n.locale), class: "btn btn-secondary" do %>
<i class="fa fa-link"></i>
<%= date_in_link %>
<% end %>
So basically what I'm doing is that I group the spendings per month and year. Then I loop trough all the user.spendings and I add this part of code above in the mix so you have a link according the date that you can click and sends you to a new page whith more infos just about this month of the year.
It works, but just for the month with no specific caracters. If I try with Février I got this as a message : invalid date for #date in the controller.
I assume it is coming from the special caracter as the rest is working.
I hope the explanation are clear, I tried my best. If you need more stuff let me know.
I think that the #date variable is missing something, but I'm not sure. Anybody to help ?
EDIT :
My url looks like this when it works :
http://localhost:3000/fr/myspendingsdetail?month=Janvier+2018
When it doesnt work :
http://localhost:3000/fr/myspendingsdetail?month=Decembre+2018
Interesting but when I put the month like this :
http://localhost:3000/fr/myspendingsdetail?month=12+2018
It works, so it's really a caracter problem
EDIT 2 :
Well it works... if I put 12 he bring me on february, same for 2, but if I put 1 for january same error as before, invalid date.
YES ! I got it !
I share my answer in case anybody needs it once.
I changed my helper :
user_spendings_paginate.group_by{ |t| (Date::MONTHNAMES[t.date.month] + " " + t.date.year.to_s) }
I keep the names of the month in english in the background, if I can say...
Then the view :
<% date_in_link = " #{month}" %>
<p><%= link_to myspendingsdetail_path(:month => month, locale: I18n.locale), class: "btn btn-secondary" do %>
<i class="fa fa-link"></i>
<%= l date_in_link.to_date, format: :pdf %>
<% end %>
As I get a String out of my helper, and I pass that trough params with my links I thought that it was there that I should change the language. So I wrote this :
l date_in_link.to_date, format: :pdf and in my yml file I went for a custom format like so : pdf: "%B %Y" for month and year.
Result :
(link)Février 2018
- spending
- spending
(link)Janvier 2018
- spending
- spending
And when I click on the link it passes the params in english but who cares. On the next page I got the date back in the language I want anyway. Mission complete !

Multiple days of week in one attribute in database

I want to implement a feature in Rails using the option of multiple checkbox. User must be able to choose the days in which he want the emails, like Monday, Tuesday, etc. This must be a list of checkboxes with day name as label and day index like 0 for Sunday, 1 for Monday, like that.
Also these fields must be checked when the user next time come here to edit.
I don't want to create separate db field for each day. This can be an array of day index stored in one database field. I am using Rails version 4.
Date::DAYNAMES will give the list of week days. Date::DAYNAMES.each_with_index will give the list of days with its index. I want to know the best way to implement the same.
Try this,
<%=select_tag 'days[]', options_for_select(Date::DAYNAMES.zip((0..6).to_a),
[selected days array goes here]
), :multiple => true%>
For using checkbox
<ul>
<% Date::DAYNAMES.zip((0..6).to_a).each do |day| %>
<li>
<%= check_box_tag 'days[]', day[1], [selected days array].include?(day[1]) -%>
<%= h day[0] -%>
</li>
<% end %>
</ul>
Hope it's help you.

Organizing by rails datetime in view

I am creating a scheduling app in Rails and I am getting stuck while trying to organize the rooms by date. When I say a room, I essentially just mean a block in the schedule. A typical event might have a lunch (one room), then a networking section (another room). Here is how I am getting the rooms:
#rooms = Room.where(event_id: #current_event.id).order(:start_time)
So that returns the rooms that belong to an event, in order of the start time. In my view I loop through and display the rooms for the event, but I want to group them in the view by the date in case there is an event that is on multiple days.
Also :start_time is a datetime type in Ruby. In human speak, what I would do is look at the date portion and if the room date is not the same as the current group, I would print the new date and continue to group the rooms that fall on that day. Here is a trivial example in case I am not being clear:
Event: Staff Retreat
July 14th, 2015
-----------------------
12:30 PM
Team building Lunch Begins
------------------------
6:30 PM
Team building Dinner Begins
------------------------
July 15th, 2015
------------------------
9:30 AM
Team building Breakfast Begins
So having the grouping of rooms in the #rooms variable that is a datetime, what would be the best way to display a table like the above? I would think that in my loop I should check if the date was the same as the previous room, and if not print the date
- #rooms.each do |room|
room.start_time.strftime("%B %d, %Y")
room.start_time.strftime("%I:%M%p")
room.name
I am having trouble with the logistics because with the Model-View-Controller concept, I feel that sorting in the view may have the view do something it shouldn't have to. I am also struggling with how to do that in the view. I would think setting a variable in the controller that would hold the temporary date as I loop through would work, but it seems like that would start to get pretty messy though. What is the best way to group the various dates from the #rooms variable?
Can you try this. this will return you a hash where date is the key and value will contain all the #rooms related to that time.
#rooms = Room.where(event_id: #current_event.id)
#rooms = Hash[#rooms.sort_by{|o| o.start_time.to_date}.group_by {|room| room.start_time.to_date}.map{|l,m| [l, m.sort_by{|k| k.start_time}]}]
now you can traverse the rooms like this in the views. im putting code in erb format.
<% #rooms.each do |k, v| %>
<%= k %>
<% v.each do |room| %>
<%= room.created_at.start_time('%I:%M %p')%>
<%= #room.name or title what so ever. %>
<% end %>
<% end %>

Using Group_by Rails

Using group_by today, trying to get my head around it and see if its the right solution for what I am trying to achieve. I have the following model
class Fixture < ActiveRecord::Base
attr_accessible :home_team, :away_team, :kickoff_time, :fixture_date
end
I want to group all the fixtures by fixture_date. So far my controller look like this
def fixturelist
#fixtures = Fixture.all
#fixture_date = #fixtures.group_by { |fd| fd.fixture_date }
end
What i would like to do then in my view is list the home_team and away team matches for that particular date
View
<% #fixture_date.each do |f| %>
<%= f %>
<% end %>
This outputs an array of all the fixtures by date, so group_by has worked. Im looking for some pointers to get this working correctly, ie see all fixtures listed for each date. seeing a working example should help me understand some more
Example
Date
Team 1 Vs Team2
Team 1 Vs Team2
Team 1 Vs Team2
Date 2
Team 1 Vs Team2
Team 1 Vs Team2
Team 1 Vs Team2
Thanks
Check this out,
http://railscasts.com/episodes/29-group-by-month
I think you will want your view code to look like this,
<% #fixture_date.sort.each do |date, fixtures| %>
<h2><%= date %></h2>
<% fixtures.each do |fixture| %>
<%= fixture.team_1 %> VS <%= fixture.team_2 %>
<% end %>
<% end %>
EDIT:
And if your fixture_date is a datetime column instead of just a date column, your controller code to look like this,
#fixture_date = #fixtures.group_by { |fd| fd.fixture_date.beginning_of_day }

How do I do a grouping by year?

I have a books model with a date type column named publish_date. On my views I'm iterating through the books and I want to group the books by year such that I have a heading for every year and books that were published on that year to be listed below the year heading.
So by starting with "2010" all books published on 2010 would be listed, then another heading "2009" with all books published in 2009 listed below it and so forth.
<% #all_books.each do |book| %>
<%=link_to book.title + ", (PDF, " + get_file_size(book.size) + ")" %>
<% end %>
By doing a book.publish_date.strftime("%Y") I am able to get the year but I do not know how to group the entries by year. Any help on this would be appreciated.
You can use group_by (see API) like (of the top of my head
<% #all_books.group_by(&:year).each do |year, book| %>
...
<% end %>
def year
self.created_at.strftime('%Y')
end
< % #all_books.group_by(&:year).each do |year, book| %>
Year < %= year %>
# render books here
< % end %>
What say?
You can use group_by for convenience, but your need can be better served by relying on DB for sorting and a each loop. This avoids the cost of client side sorting and hash manipulations for grouping.
Somewhere in your controller
#all_books = Book.all(:order => "publish_date DESC")
In your view
<%year = nil
#all_books.each do |book|
if year.nil? or year > book.publish_date.year
year = book.publish_date.year
%>
<h1> <%=year%><h1>
<%end % >
<%=link_to book.title + ", (PDF, " + get_file_size(book.size) + ")" %>
<%end %>
The quick and dirty approach is to simply group_by the year and iterate over those:
#all_books.group_by { |b| b.created_at.year }.each do |year, books|
# All books for one year, so put heading here
books.each do |book|
# ...
end
end
This requires sorting within the Rails application, so you will need to retrieve all relevant records in order to have the data properly organized. To do the sort on the server you will probably need to introduce a year column and keep it in sync with the created_at time.

Resources