Ruby on rails 用于编辑数据对象的Rails实例方法

Ruby on rails 用于编辑数据对象的Rails实例方法,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我试图用一些规则压缩一个大数据集,然后返回对象 我在模型中所做的是: class Network < ActiveRecord::Base def condense self.each do |row| #Maybe delete row end return self end end class网络

我试图用一些规则压缩一个大数据集,然后返回对象

我在模型中所做的是:

class Network < ActiveRecord::Base
  def condense
    self.each do |row|
      #Maybe delete row
    end
    return self
  end
end
class网络
所以,也许我误解了,但打电话给Network.all.condence不起作用

undefined method `condense' for #<Network::ActiveRecord_Relation

未定义的#方法“concure”您已经定义了一个实例方法,而您想要的是一个
网络
的单例方法:

def self.condense
  # now `self` here is a `Network` class itself
  all.each do |row| # iterate over each instance of the class
  end
end
用法:

Network.condense

请注意,使用
all.each
是非常昂贵的操作,因为它将在处理之前将所有内容加载到内存中-可能有一种方法可以使用数据库层来完成您正在做的事情吗?

您唯一的问题是您不了解
自身。以下是一条基本经验法则:

  • 实例方法中的
    self
    引用类的当前对象
  • 类方法中的
    self
    指类本身

那么,你能告诉我你的代码中的2个
self
是指什么吗?

你可以创建一个类,该类包含你想要
压缩的
网络数组

class NetworkCondenser
  def initialize(networks)
    @networks = networks
  end

  def call
    @networks.each do |network|
      # do your stuff here
    end
    @networks
  end
end
像这样使用它,从控制器或控制台或其他任何地方

networks = Network.take(100)
condensed_networks = NetworkCondenser.new(networks).call
编辑:

还有另一种方法,那就是对活动记录数组中的每个项调用方法
concurate

class Network < ApplicationRecord
  def condense
    # do your stuff here on a single instance only
    # e.g. name = name.upcase if something
  end
end

哪种解决方案更好取决于您的品味和需求,我想,对于更复杂的情况,我更喜欢第一种解决方案。

我理解单身汉。我已经试过了,效果很好。但是我希望在实例中能够灵活地使用wathever对象。就像网络一样。拿(100)。压缩或网络。在哪里(某物:“123”)。全部。condense@JonasUlveseth
Network.take(100)
将返回一个
数组的实例
,并将为…
抛出
未定义的方法“condence”。是的,我知道它失败的原因。只是认为这是一种干净的方法,我不明白没有一种方法可以绕过它。我可以将对象传递到任何方法,它都会工作。但是处理这样的实例不是很好吗。@JonaSolveSeth我认为,你可以创建一个包装器(显然是一个新的答案),self指的是实例中的数据对象,就像Network.new一样,self中有一个新对象。所以我想,当启动一个类似网络的方法时,我应该能够访问网络。就像selfAah一样,我们有了它!非常感谢你。这正是我所期待的,尽管我不明白为什么不能继续直接基于对象的活动记录数组处理实例。会更好更干净。即使有了这个解决方案,也感觉像是迈出了第一步many@JonasUlveseth我用这个网络的一个可能的解决方案更新了答案。each(&:concure)就像each中的each?那么,它只是对数组中的每个项调用
concure
方法。
networks = Network.take(100)
networks.each(&:condense)