I'm trying to show all toys that a client uses.
The problem is that is showing all toys without the state selected.
When I select a state the result should be depending of the status selected.
Tables:
|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
Here is controller:
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
Here the models:
class Client < ActiveRecord::Base
has_many :toys
end
class Toy < ActiveRecord::Base
belongs_to :client
end
Here is the view:
<% 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" %>
Here is the partial view:
<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>
The partial view is showing this:
I'm trying to show the information group by client like this:
I tried
<% @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>
Please somebody can help me with this?
All kind of help will be accepted.
You can do this 2 ways. This simpler approach is to group your rows before you present them using group_by
(this assumes Ruby 1.8.7 or later):
<% @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 %>
The other approach would be to group using SQL/ActiveRecord, which will actually be more efficient. I don't recall the exact format used in Rails 2.x, but it should be something like this:
@client_groups = Toy.find(:all, :include => :client,
:conditions=>['status IN (0,1,2)' ],
:group => 'client_id' )
And then use the already grouped @client_groups
collection as above.
Note that I used :include
to eager load the client
association (to avoid an N+1 situation where each toy triggers an additional query to the server to find the client) - this should be done regardless of the grouping strategy. You can also refactor your controller code to keep it DRY:
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