views:

67

answers:

3

Hello, I have a job model which has many attributes. I would like to use graphics to display the sum of some of these attributes. For that, I am using the following code in the javascript portion of the view which produces the graph:

<% for job in @daily_jobs %>
          ['<%= job.day %>',<%= job.walltime %>],
<% end %>

This returns this:

['2010-07-25', 1234],
['2010-07-26', 3456],
['2010-07-27', 1234],

Which is working fine. However, I do not only want to create graphs of the atribute "walltime", but for many other atributes: memory, cpu, etc...So i would have to create functions such as:

<% for job in @daily_jobs %>
              ['<%= job.day %>',<%= job.cpu %>],
<% end %>

AND

<% for job in @daily_jobs %>
              ['<%= job.day %>',<%= job.memory %>],
<% end %>

to create the other graphs, but this is not DRY at all, I would like a single function in which I could pass the atribute as an argument. But I do not know how to do this.

for example:

function(cpu) 

would return

['<%= job.day %>',<%= job.cpu %>],

and

function(walltime) 

would return

['<%= job.day %>',<%= job.walltime %>],
+1  A: 
<% for job in @daily_jobs %>
    ['<%= job.day %>',<%= job.attr(:cpu) %>],
<% end %>

class Job
  def attr attribute
    attribute = self.send(attribute)
    .. do your staff ..
  end
end

UPD

class Job
  def self.attributes_List jobs, attribute
    items = jobs.inject("") do |result, job|
      result + "['#{job.day}', #{job.send(attribute)}]" 
    end
    "[#{items.join(',')}]"
  end
end

<%= Job.attributes_List(@daily_jobs, :cpu) %>
fantactuka
Hello Fantactuka, I am afraid I do not follow your solution, as I understand, I still must specify within the "for in" loop, which is the atribute I need to access. What I had in mind was a function such as function(attribute)which would do job.attribute
jalagrange
So you want the function that will get the attribute name and return [date, attr], [date, attr]?
fantactuka
exactly, for example: function(cpu) would return['<%= job.day %>',<%= job.cpu %>],and function(walltime) would return['<%= job.day %>',<%= job.walltime %>],
jalagrange
+3  A: 

you could do something simpler

attr_list = [:cpu, :walltime, :memory]

then iterate through jobs

<% for job in @daily_jobs %>
    <% attr_list.each do |attr| %>
      ['<%= job.day %>',<%= job.send(attr) %>],
    <% end %>
<% end %>

Another solution would make a method in Job model something like:

def as_js_attr(attr)
  "['#{self.day}', #{self.send(attr)}],"
end

and increment that previous loop with

<% for job in @daily_jobs %>
   <% attr_list.each do |attr| %>
     <%= job.as_js_attr(attr) %>
   <% end %>
<% end %>
Angelus
+1  A: 

You could add several methods to you job class to do that:

class Job

  # returns "[['2010.07.25', 145], ['2010.07.26', 143]]"
  def self.graph_data jobs, attr
    data = jobs.collect {|j| j.graph_item_for attr}.join(', ')
    "[#{data}]"
  end

  # returns ['2010.07.25', 14]
  def graph_item_for attr
    "['#{self.day}', #{self.send(attr)}]"
  end

end

and after call it:

cpu_graph_data = Job.graph_data @daily_jobs, :cpu
Tumtu