Можно ли выгрузить ассоциацию ActiveRecord? - PullRequest
0 голосов
/ 21 марта 2011

Я столкнулся с ситуацией, когда модель, сохраняемая во флэш-памяти, вызвала ошибку marshall data too short и обнаружил, что причина этого заключается в том, что загружалась огромная ассоциация, а затем при вводе в сеанс данные были слишком большими для поле.

Мои занятия выглядят примерно так:

class Location < ActiveRecord::Base
  belongs_to :country
  belongs_to :state
  belongs_to :city
end

class Country < ActiveRecord::Base
  has_many :states
  has_many :locations
end

class State < ActiveRecord::Base
  belongs_to :country
  has_many :cities
  has_many :locations
end

class City < ActiveRecord::Base
  belongs_to :state
  has_many :locations
end

К сожалению, проверка в Location обращается к self.state.cities, который загружает в память все города для этого штата (в данном случае, более 1000 записей). Таким образом, когда объект Location проходит через flash, это вызывает вышеуказанную ошибку.

Я понимаю, что код можно реорганизовать так, чтобы он не имел доступа к ассоциации (на самом деле, это то, что я делал в данный момент), но мне было интересно, есть ли способ выгрузить ассоциацию данные из памяти (конечно, не удаляя их из базы данных).

В этом проекте используется Rails 2.3.4, и, к сожалению, в настоящее время я не могу его обновить.

1 Ответ

1 голос
/ 21 марта 2011

Часть 1: Решение указанной проблемы:

Чтобы очистить загруженные данные ассоциации, используйте метод target для ассоциации:

location.state.cities.target=[]

Если у вас есть доступ к cities сейчас:

location.state.cities
=> []

Часть 2. Неуклюжий способ избежать проблемы:

Избегайте загрузки ассоциации при доступе к cities.Используйте

self.state.cities.all 

Вместо

self.state.cities

Часть 3. Что-то пахнет подозрительно:

Почему вы храните объекты для вспышки?Flash обычно предназначен для отправки текстовых сообщений.Если вы назначите не строки для flash, вы сразу же получите ограничение на размер файла cookie.

Кроме того, когда вы проверяете, зачем загружать все города?Значит ли это, что вы проходите валидацию в Ruby?Можете ли вы опубликовать код проверки?В большинстве случаев вы можете оптимизировать это, переместив проверку в БД.

Редактировать: Расширенный ответ на основе комментария

Я следую этому шаблону в Rails 2.3.x.Переменные, к которым я хочу обратиться в представлении, связанном с действием edit, всегда являются подмножеством переменных, доступных в действии update.

class ProductsController < ApplicationController

  before_filter :init_data, :only => [:new, :create, :edit, :update, 
                                      :destroy, :show]
  def update
    @product.attributes = params[:product]
    if @product.save
      flash[:notice] = "Successfully saved the product."
      redirect_to  product_path(@product)
    else
      render :action => 'edit'
    end
  end

private
  def init_data
    switch(action.to_sym)
      when :new, :create
        @product = Product.new(params[:product])
      when :edit, update, :destroy, :show 
        @product = Product.find(params[:id])
    end
  end    
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...