Ruby passing different attribute arguments to same function
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 %>],
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 %>
<% 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) %>
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
精彩评论