Rails 5.1 group_by年和月,并显示两者 [英] Rails 5.1 group_by year and month and show both

查看:137
本文介绍了Rails 5.1 group_by年和月,并显示两者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的费用开发一个Rails应用程序。

我有3个模型,例如:用户,支出和货币。
我可以通过表单创建支出,我有一个标题,描述,金额,currency_id,user_id。所有的关系都已经制作好了。



我使用用户控制器中的 show.html.erb 来显示来自current_user的所有费用。这工作正常。然后,我将这些费用分组在一起并按日期分类。我确实做了两个小组,第一个是今天和其余的。因此,在显示屏上,它向我显示了我创建的今日(第一组)的费用清单,然后显示了来自前一日期(第二组)的费用的月份清单。现在它显示了这一点:

 今天
费用1 ...
费用2 ...

1月
...
...
...

12月
...
。 ..

etc ...

我想在本月的旁边添加一年,以便它显示如下:

 今天
...
...

2018年1月
...
...

2017年12月
.. 。
...

除此之外,我希望本月和年份作为一个链接,当你点击它时,你会进入一个新的页面,显示这个特定月份的所有费用。



这就是它。是的,我也使用了will_paginate。



现在我所做的是让我开始使用 UsersController

  class UsersController< ApplicationController 

def show

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

#将所有消息和分组转换为两组今天的消息和其他消息
@grouped_spendings = @ user_spendings.group_by {| t | t.date.to_date == DateTime.now.to_date}

if @ user_spendings.present?
#创建月明智的消息组
@month_wise_sorted_spendings = @ user_spendings.group_by {| t | t.date.month}
end
end

我的 show view有点长(我没有粘贴will_paginate):

 <%if @ grouped_spendings.present? &安培;&安培; @grouped_spendings [真] .present? %GT; 

< table>
< thead>
< tr>
< th>标题< / th>
< th>说明< / th>
< th>金额< / th>
< th>货币< / th>
< th>创建< / th>
< th>操作< / th>
< / tr>
< / thead>

< h3>今天< / h3>

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

<%end%>

< / table>

<%end%>

<%如果@ month_wise_sorted_spendings.present? %GT;
<%@ month_wise_sorted_spendings.each do | hash_elements |%>

< table>
< thead>
< tr>
< th>标题< / th>
< th>说明< / th>
< th>金额< / th>
< th>货币< / th>
< th>创建< / th>
< th>操作< / th>
< / tr>
< / thead>

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

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

<%end%>

< / table>

<%end%>
<%end%>

对不起,这个庞大的代码我希望你不要盲目...



我怎样才能设法获得月份和年份,并在此之后建立链接。我已经尝试了一些东西,比如修改 show 中的这一行:<%= Date :: MONTHNAMES [hash_elements.first]%> ; 。我得到的东西是Date :: MONTHNAMES将实际的月份数字变成了月份名称,而hash_elements.first给了我实际的月份数字,在这里hash_elements.last给我所有关于我的费用的信息。

Then我喜欢,好吧,也许我应该去控制器,并在这个变量中添加年份 @month_wise_sorted_spendings = @ user_spendings.group_by {| t | t.date.month} 。这个group_by现在只对当前的月份进行分组,所以我尝试添加 t.date.year ,但是在视图中我不能使用Date :: MONTHNAMES。所以在这里没有成功...

好吧,我有点失落,任何帮助或提示,将不胜感激。

非常感谢

解决方案

好吧,我让所有的工作都做好了!
也许你们有些人想看看它是怎么样的,所以我们去

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

#Retrives all messages and分为两组今天的消息和其他消息
@grouped_spendings = @ user_spendings.group_by {| t | t.date.to_date == DateTime.now.to_date}

if @ user_spendings.present?
#创建月明智的消息组
@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]})#获取每月的第一天
@user_spendings_month = @ current_user.spendings.order( 'date DESC')。paginate(:page => params [:page],:per_page => 30).where(:date => @date .. @ date.end_of_month)#获取当月的帖子
@user_amount = Currency.joins(:spe​​ndings)。
select(:symb,'SUM(spendings.amount)AS amount')。
其中(花费:{id:@ user_spendings_month.map(&; id)})。
group(:symb)
else
@user_spendings_month = @ current_user.spendings.all.order('date DESC')
end

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

结束

我改变了 @month_wise_sorted_spendings 变量以符合我的需要:月份按名称和年份。我还添加了def细节,因为我希望能够 link_to 所有月/年转到其他页面并查看有关本月的具体数据。

 <%if @ grouped_spendings.present? &安培;&安培; @grouped_spendings [真] .present? %GT; 

< table class =table table-striped table-bordered table-responsive>
< thead>
< tr>
< th>标题< / th>
< th>说明< / th>
< th>金额< / th>
< th>货币< / th>
< th>创建< / th>
< th>操作< / th>
< / tr>
< / thead>
< h3 class =btn btn-secondary col-1>今日< / h3>
< / br>< / br>
< tbody>
<%@grouped_spendings [true] .each do | spending | %GT;
< tr>
< td><%= spend.title%>< / td>
< td><%= spend.description%>< / td>
< td><%='%.02f'%spending.amount%>< / td>
< td><%= spending.currency.symb%>< / td>
< td><%= spend.date.strftime('%d%B%Y')%>< / td>
< / tr>
< / tbody>

<%end%>

< / table>
<%end%>

<%如果@ month_wise_sorted_spendings.present? %GT;
<%@ month_wise_sorted_spendings.each do | month,支出|%>

< table class =table table-striped table-bordered table-responsive>
< thead>
< tr>
< th>标题< / th>
< th>说明< / th>
< th>金额< / th>
< th>货币< / th>
< th>创建< / th>
< th>操作< / th>
< / tr>
< / thead>


< / br>
<%date_in_link =#{month}%>
< p><%= link_to user_detail_path(@current_user,:month => month),class:btn btn-secondary col-1do%>
< 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-1do%>
< i class =fa fa-file-pdf-o>< / i>
PDF
<%end%>< / p>
< / br>
< tbody>
<百分比花费%GT;
< tr>
< td><%= spend.title%>< / td>
< td><%= spend.description%>< / td>
< td><%='%.02f'%spending.amount%>< / td>
< td><%= spending.currency.symb%>< / td>
< td><%= spend.date.strftime('%d%B%Y')%>< / td>
< / tr>
< / tbody>

<%end%>

< / table>

<%end%>
<%end%>

< / div>

我使用 month param 来获取并通过 @user_spendings_month @page 使用到新页面中。
在月份/年份链接旁边,我添加了一个打印关于这些信息的pdf的链接,我认为它可以得心应手。我使用与pdf中的show view相同的变量。多田!太棒了!

我希望如果你没有得到某些东西,就足够清楚了,只需写一条评论即可!


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 }. 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 !

这篇关于Rails 5.1 group_by年和月,并显示两者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆