القضبان: مرشح محدد في ملف lib المطلوب في البيئة. RB يختفي من Filter_Chain في بيئة الإنتاج. لماذا ا؟

StackOverflow https://stackoverflow.com/questions/620146

سؤال

في تطبيق Rails الخاص بي ، لدي ملف في Lib ، من بين أشياء أخرى ، يقوم بإعداد مرشح يعمل على جميع وحدات التحكم.

عند تشغيل بيئة التطوير ، كل شيء يعمل بشكل جيد. ومع ذلك ، في إطار الإنتاج ، يختفي المرشح. الشيء المضحك هو ، من خلال فحص filter_chain, ، لاحظت بقاء المرشحات الأخرى ، على سبيل المثال. تلك المحددة في المكونات الإضافية ، أو في وقت لاحق في فئة وحدة التحكم المحددة.

لقد اختبرت هذا مع كل من Rails Edge و V2.3.0.

تحديث الاختبار:

لقد اختبرت الآن مع القضبان القديمة ووجدت أن المشكلة تتواجد إلى v2.1.0 ، ولكن ليس في v2.0.5 ، لقد شطرت عليها ووجدت 986aec5 القضبان تلتزم أن تكون مذنبا.


لقد عزلت السلوك إلى حالة الاختبار الصغيرة التالية:

# app/controllers/foo_controller.rb
class FooController < ApplicationController
  def index
    render :text => 'not filtered'
  end
end

# lib/foobar.rb
ActionController::Base.class_eval do
  before_filter :foobar
  def foobar
    render :text => 'hi from foobar filter'
  end
end

# config/environment.rb (at end of file)
require 'foobar'

إليك الإخراج الذي أحصل عليه عند الركض تحت تطوير بيئة:

$ script/server &
$ curl localhost:3000/foo
> hi from foobar filter

وهنا هو الإخراج ل إنتاج بيئة:

$ script/server -e production &
$ curl localhost:3000/foo             
> not filtered

كما ألمح من قبل ، فإنه يعمل بشكل جيد لأي بيئة عندما أفعل نفس الشيء عبر البرنامج المساعد. كل ما أحتاجه هو وضع ما هو تحت lib/foobar.rb في البرنامج المساعد init.rb ملف.

لذا ، بطريقة ما لديّ بالفعل حل بديل ، لكنني أود أن أفهم ما يجري وما الذي يجعل المرشح يضيع عندما يكون في الإنتاج.

إنني أخمِّع أنه شيء ما بطرق مختلفة تتعامل معها القضبان في البيئات المختلفة ، لكنني بحاجة إلى الحفر بشكل أعمق.

تحديث

في الواقع ، لقد ضاقت الآن إلى خط التكوين التالي:

config.cache_classes = false

إذا ، في production.rb, config.cache_classes يتغير من true إلى false, ، تطبيق الاختبار يعمل بشكل صحيح.

ما زلت أتساءل لماذا تسبب إعادة تحميل الفصل مثل هذا الشيء.

هل كانت مفيدة؟

المحلول

فريدريك تشيونغ على قائمة القضبان كان الاجابة:

لأن Cache_Classes يفعل أكثر من مجرد ذلك. الطريقة التي تعمل قبل عمل المرشحات ، إذا كانت Foo <bar ، فسيتم توريث تلك المرشحات المحددة في الشريط في تلك المرحلة

في وضع التطوير ، يبدأ التطبيق ، مطلوب ملفك ، والمرشح الذي تمت إضافته إلى ActionController :: base. في وقت لاحق يأتي الطلب الأول ، يتم تحميل وحدة التحكم ويرث ذلك التصفية.

عندما تكون Cache_Classes صحيحة ، يتم تحميل جميع فئات التطبيق الخاصة بك في وقت مبكر. يحدث هذا قبل الحاجة إلى ملفك ، لذلك جميع وحدات التحكم الخاصة بك موجودة بالفعل عند تشغيل هذا الملف وبالتالي لا يكون له أي تأثير. يمكنك حل هذا من خلال طلب هذا الملف من مُهيئ (ضمان تشغيله قبل تحميل فئات التطبيق) ، ولكن في الحقيقة لماذا لا تضع هذا في التطبيق.

فريد


كانت حالتي الحقيقية في الواقع أكثر مشاركة ، وهذه هي الطريقة التي وجدتها لحل المشكلة:

config.after_initialize do
  require 'foobar'
end

ال after_initialize يتم تشغيل الكتلة بعد تهيئة الإطار ولكن قبل تحميل ملفات التطبيق ، وبالتالي ، سوف يؤثر ActionPack::Base بعد تحميله ، ولكن قبل أن تكون وحدات تحكم التطبيق.

أعتقد أن هذه هي الطريقة الآمنة عمومًا للتعامل مع كل التحميل المسبق الذي يستمر في الإنتاج.

نصائح أخرى

Drop a ruby script in

RAILS_ROOT\config\initializers

that contains

require "foobar.rb"

This invokes the before_filter for me.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top