ActiveRecord:将has_many列表视为一个简单数组

Den*_*nis 4 activerecord ruby-on-rails has-many

考虑一下这个简单的:has_many关系:

class Basket < ActiveRecord::Base
    has_many :apples
    ...
end

class Apple < ActiveRecord::Base
    belongs_to :basket
end
Run Code Online (Sandbox Code Playgroud)

现在,我在Basket类中有一个方法,其中我想创建'apples'数组的临时副本并操作临时副本.对于初学者,我想在临时副本中添加一个新元素,如下所示:

class Basket < ActiveRecord::Base
    has_many :apples

    def do_something
        #create a temporary working copy of the apples array
        temp_array = self.apples

        #create a new Apple object to insert in the temporary array
        temp_apple = Apple.new

        #add to my temporary array only
        temp_array << temp_apple

        #Problem! temp_apple.validate gets called but I don't want it to.
    end
end
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我发现当我尝试将它添加到临时数组时,会在临时Apple对象上调用validate例程.我创建临时数组的全部原因是为了避免主数组带来的所有行为,例如验证,数据库插入等......

也就是说,我确实找到了一种蛮力的方法来避免这个问题,在for循环中一次创建一个temp_array对象,如下所示.这有效,但很难看.我想知道是否有一种更优雅的方式来实现这一目标.

class Basket < ActiveRecord::Base
    has_many :apples

    def do_something
        #create a temporary working copy of the apples array
        temp_array = []
        for x in self.apples
            temp_array << x
        end

        #create a new Apple object to insert in the temporary array
        temp_apple = Apple.new

        #add to my temporary array only
        temp_array << temp_apple

        #Yippee! the temp_apple.validate routine doesn't get called this time!.
    end
end
Run Code Online (Sandbox Code Playgroud)

如果有人比我听到的更能解决这个问题,我很乐意听到.

谢谢!

alo*_*ony 9

问题是它self.apples实际上不是一个数组 - 它是一个关系,一旦你对它应用数组/可枚举方法就会解决它.所以,在此之后:temp_array = self.apples甚至没有触发SQL查询.

强制获取数据并摆脱所有关系行为的简单解决方案就是使用方法all:

#create a temporary working copy of the apples array
temp_array = self.apples.all
Run Code Online (Sandbox Code Playgroud)