简体   繁体   中英

Rails 5.1 group_by year and month and show both

I'm working on a rails app for my expenses.
I have 3 models like : user, spending and currency. I can create a spending via form, I have a title, description, amount, currency_id, user_id. All the relations are made and working.

I use my show.html.erb from the user controller to display all the expenses from the current_user. That works fine. I then I grouped the expenses together and sort them by date. I did actually 2 groups, the first one which is today and the rest. So on the display it shows me a list of the expenses I created Today (first group) and then a list of month with the expenses from a previous date (second group). For now it shows this :

Today
Expense 1...
Expense 2...

January
...
...
...

December
...
...

etc...

I would like to add the year as well next to the month so that it shows up like this :

Today
...
...

January 2018
...
...

December 2017
...
...

I addition to that I'd like this month and year to be a link so that when you click on it you go to a new page that show all the expenses for this specific month only.

Thats about it. Ah yes, I use will_paginate as well.

Now what I did is this, lets start with my UsersController :

class UsersController < ApplicationController

    def show

    @user_spendings = @current_user.spendings.all.order('date DESC').paginate(:page => params[:page], :per_page => 10)

    #Retrives all messages and divides into two groups todays messages and other messages
    @grouped_spendings = @user_spendings.group_by{ |t| t.date.to_date == DateTime.now.to_date }

    if @user_spendings.present?
      #Create month wise groups of messages      
      @month_wise_sorted_spendings  = @user_spendings.group_by{ |t| t.date.month }
    end    
end

And my show view is a little bit longer (I didn't paste the will_paginate) :

<% if @grouped_spendings.present? && @grouped_spendings[true].present? %>

<table>
<thead>
    <tr>
        <th>Title</th>
        <th>Description</th>
        <th>Amount</th>
        <th>Currency</th>
        <th>Created</th>
        <th>Actions</th>
    </tr>
</thead>

  <h3>Today</h3>

<tbody>
  <% @grouped_spendings[true].each do |spending| %>
  <tr>
    <td><%= spending.title %></td>
    <td><%= spending.description %></td>
    <td><%= '%.02f' % spending.amount %></td>
    <td><%= spending.currency.symb %></td>
    <td><%= spending.date.strftime('%d %B %Y') %></td>
  </tr>
</tbody>

<% end %> 

</table>

<% end %>

<% if @month_wise_sorted_spendings.present? %>
<% @month_wise_sorted_spendings.each do |hash_elements|%>

<table>
<thead>
    <tr>
        <th>Title</th>
        <th>Description</th>
        <th>Amount</th>
        <th>Currency</th>
        <th>Created</th>
        <th>Actions</th>
    </tr>
</thead>

  <h3><%= Date::MONTHNAMES[hash_elements.first] %></h3>

<tbody>
  <% hash_elements.last.each do |spending| %>
  <tr>
    <td><%= spending.title %></td>
    <td><%= spending.description %></td>
    <td><%= '%.02f' % spending.amount %></td>
    <td><%= spending.currency.symb %></td>
    <td><%= spending.date.strftime('%d %B %Y') %></td>
  </tr>
</tbody>

<% end %> 

</table>

<% end %>
<% end %>

Sorry for that giant code I hope your not blind...

How could I manage to get the month and the year and to make it a link after that. I tried already a few things such as modify this particular line in the show : <%= Date::MONTHNAMES[hash_elements.first] %> . The thing I got is that Date::MONTHNAMES changes the actual month number into the month name and hash_elements.first gives me the actual month number where hash_elements.last gives me all the informations about my expense.
Then I was like, ok, maybe I should go to the controller and add the year over there in this variable @month_wise_sorted_spendings = @user_spendings.group_by{ |t| t.date.month } @month_wise_sorted_spendings = @user_spendings.group_by{ |t| t.date.month } . This group_by only groups the month for now so I try to add t.date.year , but then in the view I can't use Date::MONTHNAMES. So no success here...

Well I'm a bit lost, any help or hint would be appreciated.
Thanks alot

Ok guys I got everything working ! Maybe some of you want to see how it looks like so there we go

    def show
        @user_spendings = @current_user.spendings.all.order('date DESC').paginate(:page => params[:page], :per_page => 15)

        #Retrives all messages and divides into two groups todays messages and other messages
        @grouped_spendings = @user_spendings.group_by{ |t| t.date.to_date == DateTime.now.to_date }

        if @user_spendings.present?
          #Create month wise groups of messages      
          @month_wise_sorted_spendings  = @user_spendings.group_by{ |t| (Date::MONTHNAMES[t.date.month] + " " + t.date.year.to_s) }
        end  
      end

    def detail
    if params[:month]
      @date = Date.parse("#{params[:month]}")  # to get the first day of the month
      @user_spendings_month = @current_user.spendings.order('date DESC').paginate(:page => params[:page], :per_page => 30).where(:date => @date..@date.end_of_month)  # get posts for the month
      @user_amount = Currency.joins(:spendings).
                     select(:symb, 'SUM(spendings.amount) AS amount').
                     where(spendings: { id: @user_spendings_month.map(&:id) }).
                     group(:symb)
    else
      @user_spendings_month = @current_user.spendings.all.order('date DESC')
    end

    respond_to do |format|
      format.html
      format.pdf {
        render template: 'views/users/detail', pdf: "eXpenses #{params[:month]}", file: "#{Rails.root}/app/views/users/detail.pdf.erb" }
    end    

  end

I changed the @month_wise_sorted_spendings variable to match my need : the month by name and the year. I also added the def detail as I want to be able to link_to all my months/year to go to a other page and see specific data about this month.

    <% if @grouped_spendings.present? && @grouped_spendings[true].present? %>

    <table class= "table table-striped table-bordered table-responsive">
    <thead>
        <tr>
            <th>Title</th>
            <th>Description</th>
            <th>Amount</th>
            <th>Currency</th>
            <th>Created</th>
            <th>Actions</th>
        </tr>
    </thead>
        <h3 class="btn btn-secondary col-1">Today</h3>
    </br></br>
    <tbody>
      <% @grouped_spendings[true].each do |spending| %>
      <tr>
        <td><%= spending.title %></td>
        <td><%= spending.description %></td>
        <td><%= '%.02f' % spending.amount %></td>
        <td><%= spending.currency.symb %></td>
        <td><%= spending.date.strftime('%d %B %Y') %></td>
      </tr>
    </tbody>

    <% end %> 

    </table>
    <% end %>

<% if @month_wise_sorted_spendings.present? %>
    <% @month_wise_sorted_spendings.each do |month,spending|%>

    <table class= "table table-striped table-bordered table-responsive">
    <thead>
        <tr>
            <th>Title</th>
            <th>Description</th>
            <th>Amount</th>
            <th>Currency</th>
            <th>Created</th>
            <th>Actions</th>
        </tr>
    </thead>


    </br>
    <% date_in_link = " #{month}" %>
          <p><%= link_to user_detail_path(@current_user, :month => month), class: "btn btn-secondary col-1" do %>
          <i class="fa fa-link"></i>
          <%= date_in_link %>
          <% end %>
          <%= link_to user_detail_path(@current_user, :month => month, format: "pdf"), class: "btn btn-secondary col-1" do %>
          <i class="fa fa-file-pdf-o"></i>
          PDF
          <% end %></p>
    </br>
    <tbody>
      <% spending.each do |spending| %>
      <tr>
        <td><%= spending.title %></td>
        <td><%= spending.description %></td>
        <td><%= '%.02f' % spending.amount %></td>
        <td><%= spending.currency.symb %></td>
        <td><%= spending.date.strftime('%d %B %Y') %></td>
      </tr>
    </tbody>

    <% end %> 

    </table>

    <% end %>
    <% end %>

    </div>

I use a month param to get the date in the URL and use into the new page via the @user_spendings_month and the @page . Next to the month/year links I added a link to print a pdf about those infos, I thought it can be handy. I use the same variables I use in the show view in the pdf. Tada ! Just great !
I hope it is clear enough if you don't get something, well just write a comment !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM