开发者

Micro-refactoring: creating a hash for JSON from objects

开发者 https://www.devze.com 2022-12-17 22:26 出处:网络
Hey, thanks in advance for the help. I have another pretty straight forward question. This isn\'t very rails-like, but it works. Is there a way to do it better? I know there\'s group_by, for dates, b

Hey, thanks in advance for the help.

I have another pretty straight forward question. This isn't very rails-like, but it works. Is there a way to do it better? I know there's group_by, for dates, but I can't figure ou开发者_如何学运维t how to use it for this. I'm still super new at ruby, but know enough to tell that there must be a better way!

def self.getRecipeNames
   recipes = Recipe.all
   names = Hash.new
   recipes.each do |recipe|
      names[recipe.id] = recipe.name
   end
   names
end

Thanks!


You can use reduce (inject in older version of Ruby) to transform your list of recipes to single hash (that's why it is reduce, it reduces to single value, which can be list/hash/whatever):

recipes = Recipe.all
names = recipes.reduce({}) do |acc,el|
  acc[el.id] = el.name
  acc 
end


This is prettier (IMO), but possibly not as efficient as your original method (or MBO's).

def self.getRecipeNames
  Hash[Recipe.all.map{|r| [r.id, r.name] }]
end

This uses the fact that Hash::[] takes an array of key/value pairs, e.g. Hash[[:a, 1], [:b, 2]] => { :a => 1, :b => 2 }.

Edit: Actually I'm sure this is half as efficient as both your original method and MBO's, because both Array#map and Hash::[] iterate through the whole array. So it's pretty, but don't use it if you have e.g. thousands of records.


If this is in the Recipe model, use :select

def self.getRecipeNames
  find(:all, :select => 'id, name')
end

controller:

@names = Recipe.getRecipeNames  
@names.to_json # etc.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号