read_inheritable_attribute, неожиданно измененный в рабочей среде - PullRequest
1 голос
/ 10 августа 2011

Это происходит в Rails 3.0.7 и 3.0.9, WEBrick и Apache.

У меня есть модуль Reportable, у которого есть метод, который записывает inheritable_attribute:

module Reportable
  module ClassMethods
    def add_report(report_name)
      instance_eval do
        write_inheritable_hash(:reportable_report_names,
          {report_name => {:dates => true, :details => 'something'})
        end
      end
    end
  end

  def self.included(base)
    base.extend(ClassMethods)
  end
end

Reportable загружается в config/initializers и класс использует его:

class User < ActiveRecord::Base
  include Reportable
  add_report :report1
  add_report :report2
end

В рабочем режиме при первой загрузке страницы после запуска сервера атрибут загружается правильно:

User.read_inheritable_attribute(:reportable_report_names)
# => {:report1 => {:dates => true, :details => 'something'},
      :report2 => {:dates => true, :details => 'something'}}

Но при загрузке второй страницы:

User.read_inheritable_attribute(:reportable_report_names)
# => {:report1 => {:dates => true},
      :report2 => {:dates => true}}

Работает как положено в разработке и в консоли в производственном режиме.Проблема появляется только в запросе POST на веб-сервере в производственном режиме.Что дает?

Ответы [ 2 ]

1 голос
/ 11 августа 2011

После многих головных болей причина была в том, что read_inheritable_attribute возвращала ссылку, а не значение.

Действие, вызывающее ошибку, перенаправлялось на другое действие, которое и являлось истинной причиной проблемы.У модуля был другой метод:

def available_reports
  read_inheritable_attribute(:reportable_report_names)
end

И другое действие сделало это:

# @model_reports = a hash of 'model_class_name'.to_sym => model.available_reports.dup
@model_reports.each do |model, model_reports|
  model_reports.each do |name, properties|
    properties = properties.keep_if... # remove per the view's requirements
  end
end

Поскольку available_reports вернул ссылку, dup ничего не сделал, а keep_ifудалил мои драгоценные значения из переменной класса.

Исправление:

properties = properties.dup.keep_if...

Спасибо тем, кто нашел время, чтобы проверить этот вопрос, хотя в нем было недостаточно информациичтобы получить правильный ответ.

1 голос
/ 10 августа 2011

Только что попробовал, работает во всех средах без проблем.Любые другие детали?


В противном случае:

  • почему вы используете instance_eval, так как вы работаете над самой моделью?

  • для передачи аргументов вы должны использовать восклицательный знак

Это приведет к:

module ClassMethods
  def add_reports(*report_names)
    report_names.each do |report_name|
      write_inheritable_hash(:loggable_report_names,
        {report_name => {:dates => true, :details => 'something'})
      end
    end
  end
end

И в модели:

include Reportable
add_reports :report1, :report2
...