试图掌握Ruby。如何优化此方法?

时间:2011-02-08 00:50:03

标签: ruby-on-rails

我一直在学习新的技巧,而且我总是在寻找更好的想法。

我有这种相当丑陋的方法。你会如何清理它?

def self.likesit(user_id, params)

  game_id = params[:game_id]
  videolink_id = params[:videolink_id]
  like_type = params[:like_type]

  return false if like_type.nil?

  if like_type == "videolink"
    liked = Like.where(:user_id => user_id, :likeable_id => videolink_id, :likeable_type => "Videolink").first unless videolink_id.nil?
  elsif like_type == "game"
    liked = Like.where(:user_id => user_id, :likeable_id => game_id, :likeable_type => "Game").first unless game_id.nil?
  end

  if liked.present?
    liked.amount = 1
    liked.save
    return true
  else  # not voted on before...create Like record
    if like_type == "videolink"
      Like.create(:user_id => user_id, :likeable_id => videolink_id, :likeable_type => "Videolink", :amount => 1) 
    elsif like_type == "game"
      Like.create(:user_id => user_id, :likeable_id => game_id, :likeable_type => "Game", :amount => 1) 
    end
    return true
  end

  return false

end

2 个答案:

答案 0 :(得分:4)

我会做类似的事情:

class User < ActiveRecord::Base  
  has_many :likes, :dependent => :destroy  

  def likes_the(obj)
    like = likes.find_or_initialize_by_likeable_type_and_likeable_id(obj.class.name, obj.id)
    like.amount += 1
    like.save
  end
end

User.first.likes_the(VideoLink.first)

首先,我认为处理模型级别的“params”哈希是错误的。当你将整个params散列传递给模型时,对我来说是一个红旗。在你的控制器范围内,你的模型应该不知道你的params hash的结构,imo。

其次,我认为在可能的情况下使用对象而不是类方法总是更清晰。你在做什么处理一个对象,没有理由在类级别上执行此操作。在控制器中查找对象应该是微不足道的。毕竟这是控制器的目的。将所有东西粘在一起。

最后,消除所有“回归虚假”和“回归真实”的疯狂。 save方法负责处理。永远不会调用方法中的最后一个“return false”,因为上面的if else子句会阻止它。在我看来,你应该很少在ruby中调用“return”,因为ruby总是返回最后一个评估的行。仅在方法的最顶部使用return来处理异常。

希望这有帮助。

答案 1 :(得分:1)

我不确定代码的其余部分是什么样的,但您可能会将其视为替代代码:

def self.likesit(user_id, params)
  return false unless params[:like_type]
  query = {:user_id => user_id,
           :likeable_id => eval("params[:#{params[:like_type]}_id]"), 
           :likeable_type => params[:like_type].capitalize}
  if (liked = Like.where(query).first).present?
    liked.amount = 1
    liked.save
  else  # not voted on before...create Like record
    Like.create(query.merge({:amount => 1})) 
  end
end

如果成功,我认为liked.saveLike.create会返回true,否则会返回nil。那unless game_id.nil?怎么样?你真的需要吗?如果是nil,则为nil并保存为nil。但您也可以查看nil的数据模型。 (验证或其他)