在Model类方法中指定当前抓取的记录

时间:2016-03-16 15:17:23

标签: ruby-on-rails ruby activerecord activerecord-relation

我有一个类方法,我想修改当前由ActiveRecord::Relation对象抓取的记录。但我不知道如何在类方法中引用当前范围。 self没有这样做。

示例:

class User < ActiveRecord::Base
  ...

  def self.modify_those_records
    #thought implicitly #to_a would be called on currently grabbed records but doesn't work
    temp_users_to_a = to_a
    ...
  end
end

我会像这样使用它:

User.some_scope.modify_those_records

所以User.some_scope会向我返回一个ActiveRecord::Relation,其中包含一堆User条记录。然后,我想修改该类方法中的那些记录,然后返回它们。

问题是:我不知道如何明确地引用&#34;那组记录&#34;在类方法中。

3 个答案:

答案 0 :(得分:4)

您可以使用current_scope

def self.modify_those_records
  current_scope.each do |user|
    user.do_something!
  end
end

如果您想根据用户的管理权限订购用户,最好使用ActiveRecord:

scope :order_admins_first, order('CASE WHEN is_admin = true THEN 0 ELSE 1 END, id')
User.some_scope.order_admins_first

此代码表示您在users表上有一个布尔列is_admin

答案 1 :(得分:2)

我认为范围与each和实例方法的组合比类方法更容易理解。作为奖励,它更容易测试,因为您可以单独测试所有步骤:

因此我代替User.some_scope.modify_those_records执行以下操作:

User.some_scope.each(&:modify)

并实现一个实例方法:

# in user.rb
def modify
  # whatever needs to be done
end

答案 2 :(得分:1)

如果您只想修改记录的顺序 - 更好的方法是将排序字段(如果您还没有)添加到模型中并按此排序。

public class HBaseBulkLoadReducer extends Reducer<ImmutableBytesWritable, Put, ImmutableBytesWritable, Put> {
      @Override
      protected void reduce(
          ImmutableBytesWritable row,
          Iterable<Put> puts,
          Reducer<ImmutableBytesWritable, Put,
                  ImmutableBytesWritable, Put>.Context context)
          throws java.io.IOException, InterruptedException
      {
        TreeMap<String,KeyValue> map = new TreeMap<String,KeyValue>();
        int count =0;
        Append nkv;
        byte[] tmp= "".getBytes();
        Put pp = new Put(tmp);
    try{
        for (Put p : puts) {
              byte[] r =  "".getBytes();
              //KeyValue kv = new KeyValue(r);
              if (count!=0){
              r = p.getRow();
              pp.add(new KeyValue(r));
              //KeyValue k = map.get(row.toString());
              //nkv = new Append(k.getRowArray());
              //nkv=nkv.add(kv);
              //map.put(row.toString(), k.clone());
              //context.write(row,nkv);
              //tmp=ArrayUtils.addAll(tmp,kv.getValueArray());
              //map.put(row.toString(),new KeyValue(kv.getRowArray(),kv.getFamilyArray(),kv.getQualifierArray(),tmp));
              count++;
              throw new RuntimeException();
              }
              else{
              r = p.getRow();
              pp = new Put(row.toString().getBytes());
              pp.add(new KeyValue(r));
              //tmp=kv.clone().getValueArray();
              //nkv = new Append(kv.getRowArray());
              //map.put(row.toString(), kv.clone());
              count++;
              throw new RuntimeException();
          }
     }
      context.write(row,pp);
      }catch(Exception e) { e.printStackTrace();}
     }

}