如何根据条件分组信息?

时间:2014-05-02 17:14:00

标签: ruby-on-rails ruby ruby-on-rails-2

我正在尝试展示客户使用的所有玩具。

问题在于显示所有未选择状态的玩具。

当我选择一个状态时,结果应该取决于所选的状态。

表:

|toys|
   |id| |name|     |client_id| |status|
     1   facebook       1         0
     2   whatsup        1         1
     3   android        2         0
     4   google         2         1
     3   iphone         3         0

|clients|
   |id| |name|
     1    ZUCK
     2    GATES
     3    JOBS

这是控制器:

def index
  if params[:status]=="3"
    @data= Toy.find(:all,:conditions=>['status IN (0,1,2)' ])
    @client_groups = Toy.find(:all, :include => :client, :conditions=>['status IN (0,1,2)' ],:group=>['client_id'] )
  else
    @data= Toy.find(:all,:conditions=>['status= ?',params[:status] ])
    @client_groups = Toy.find(:all, :include => :client,:conditions=>['status = ?',params[:status] ],:group =>['client_id'] )
  end
end

这里的模型:

class Client < ActiveRecord::Base
   has_many :toys
end

class Toy < ActiveRecord::Base
   belongs_to :client     
end

以下是观点:

<% form_tag :controller=>"toy",:action=>"index" do %>
  Status:
  <%= select_tag "status", "<option value=\"3\">All</option>"+ options_for_select([ ["Active",0],["Inactive",1]],params[:status].to_i) %>
  <%= submit_tag "SEARCH", :name => nil %>
<% end %>
<%= render :partial=>"table" %>

以下是部分视图:

<table border="1">
<% @client_groups = @data.group_by{|toy| toy.client.name} %>
<% @client_groups.each do |client_name, toys| %>
  <tr><td>Client Name</td></tr>
  <tr><td><%= client_name %></td></tr>
  <tr>
     <td></td>
     <td>Name Toy</td>
     <td>State Toy</td>
  <tr>
  <% toys.each do |toy| %>
  <tr>  
     <td></td>
     <td><%= toy.name  %></td>
     <td><%= toy.status %></td>
  </tr> 
  <% end %>
<% end %>
</table>

部分视图显示:

enter image description here

我正在尝试按客户端显示信息组:

enter image description here

我试过

<% @client_groups = @data.group_by{|toy| toy.client.name} %>
<% @client_groups.each do |client_name, toys| %>
  <tr><td>Client ID</td><td>Client Name</td></tr>
  <tr><td><%= client_name.id %></td></tr>
  <tr><td><%= client_name.name %></td></tr>
  <tr>
     <td></td>
     <td>Name Toy</td>
     <td>State Toy</td>
  <tr>

enter image description here

请有人帮我这个吗?

将接受所有类型的帮助。

1 个答案:

答案 0 :(得分:2)

你可以这两种方式做到这一点。这种更简单的方法是在使用group_by(假设Ruby 1.8.7或更高版本)呈现行之前对行进行分组:

<% @client_groups = @data.group_by{|toy| toy.client } %>
<% @client_groups.each do |client, toys| %>
  <tr><td>Client Id</td><td>Client Name</td></tr>
  <tr><td><%= client.id %></td><td><%= client.name %></td></tr>
  <tr>
    <td></td>
    <td>Name Toy</td>
    <td>State Toy</td>
  <tr>
  <% toys.each do |toy| %>
    <tr>  
      <td></td>
      <td><%= toy.name  %></td>
      <td><%= toy.status %></td>
    </tr> 
  <% end %>
<% end %>

另一种方法是使用SQL / ActiveRecord进行分组,实际上效率更高。我不记得Rails 2.x中使用的确切格式,但它应该是这样的:

@client_groups = Toy.find(:all, :include => :client, 
                                   :conditions=>['status IN (0,1,2)' ], 
                                   :group => 'client_id' )

然后使用上面已经分组的@client_groups集合。

请注意,我使用:include急切加载client关联(以避免N + 1情况,其中每个玩具触发对服务器的额外查询以找到客户端) - 这应该完成无论分组策略如何。您还可以重构控制器代码以使其保持干燥状态:

status_condition = params[:status]=="3" ? 
  ['status IN (0,1,2)'] : 
  ['status= ?',params[:status] ]
@data= Toy.find(:all, :conditions=> status_condition, 
                         :include => :client)            # add :group if grouping in the query