选择性ActiveRecord

时间:2012-04-12 12:59:26

标签: ruby-on-rails activerecord

说我有一张桌子'用户'。 用户可以在我的表中存在3次(记录),处于3种不同的状态(state1,state2,state3)。 将创建第一个state1,然后是state2,... 如果state3存在,我不想再看看state1和state2了,但为了以后的目的,我必须将它们保存在我的表中。 所有3条记录都具有相同的uuid。

如果我想收集所有用户,我不能使用User.all(因为他会给我同一个用户的所有3个州)。

我的模型中是否有一个简短的解决方案?现在我正在收集所有的uuid,并且对于每个uuid,我将检查哪个是最新状态,然后我将这些记录放在一个数组中。 这个数组的问题在于它只是一个'数组'而不是ActiveRecord对象。

@uuid = []
@users = [] #will contain only the latest states at the end

User.all.each do |u|
  @uuid << u.uuid unless @uuid.includes?(u.uuid)
end

@uuid.each do |u|
  if user = User.find_by_state_and_uuid(3, u)
     @users << user
  elsif user = User.find_by_state_and_uuid(2, u)
     @users << user
  elsif user = User.find_by_state_and_uuid(1, u)
     @users << user
  end
end

如何将此逻辑转换为ActiveRecord对象?

简而言之:User.magic_function只返回每个uuid的最新状态

提前致谢! 沃特

3 个答案:

答案 0 :(得分:1)

如果您提前计划,您可以随时对您的州进行排序并返回“最高”州。如果从一个到另一个的线性进展,这种方法很有效。举个例子:

user = User.where(:uuid => u).order('users.state DESC').first

对于更复杂的过渡,你无法使用这个技巧。您可以尝试使用其他列进行排序,例如在created_at时间之前获取最后一列。

从设计的角度来看,在不同的状态下拥有多个用户记录似乎非常不寻常。更好的计划可能是将用户记录的状态驱动部分拆分为单独的表,并在那里进行状态跟踪,所有内容都链接回单个用户记录。

答案 1 :(得分:0)

您是否考虑过使用scopes?您应该能够为每个用户状态创建一个范围,然后使用它们进行查询。

答案 2 :(得分:0)

尝试:

User.get_user(state, uuid)

在您的用户模型中创建范围:

  scope :get_user, lambda { |*args| { :conditions => ["state = ? AND uuid = ?",args.first , args.second ] }}