bootstrap-sass 在将模块添加到应用程序控制器时退出 Rails 中的工作?

bootstrap-sass quits working in Rails when adding module to application controller?

真的,它只是有一天停止加载。我一直在使用 Rails 5.0.0.beta3。日志不显示任何从 assets/ 加载任何内容的尝试。一切都按照文档指示进行了设置。 宝石文件:

gem 'sass-rails', '~> 5.0'
gem 'bootstrap-sass', '~> 3.3.6'

application.scss:

@import "bootstrap-sprockets";
@import "bootstrap";

application.js

//= require jquery
//= require jquery-ui
//= require bootstrap-sprockets
//= require jquery_ujs
//= require turbolinks
//= require_tree .

另外,尝试将 require 'bootstrap-sass' 添加到 config.ru。它没有帮助。

更新:

所以,看起来 bootstrap 每次我尝试向我的应用程序控制器添加模块时都会死机,如下所示:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  include SomeModule
end

有什么想法吗?

这是模块:

module BeforeOrAfter
  attr_accessor :past
  attr_accessor :future

  require "date"
  def initialize
    @future = []
    @past = []
  end

  def before_or_after(event)
    if event < DateTime.now
      @past << event.id
    else
      @future << event.id
    end
  end
end

您遇到的错误是由于覆盖了 ApplicationController 上的 initialize 而没有调用 super,如下所示:

require "date"
module BeforeOrAfter
  attr_accessor :past
  attr_accessor :future

  def initialize(*args)
    @future = []
    @past = []
    super
  end

  def before_or_after(event)
    if event < DateTime.now
      @past << event.id
    else
      @future << event.id
    end
  end
end

另一方面,在澄清了你的问题之后,这似乎是完全没有必要的。您有一个表示事件的对象的可枚举(例如数组),您只想将它​​们分成过去和未来的事件。 Enumerable#partition 方法非常适合此目的:它接受一个块并将输入分成两个数组,一个包含所有匹配条件的项目,另一个包含所有不匹配条件的项目。所以,我的建议是:

  • 删除您试图包含的模块
  • 在需要拆分事件的控制器中添加分区代码。

假设您的数组名为 events 并且包含具有 time 字段的类似 ActiveRecord 的对象:

(@past, @future) = events.partition { |event| event.time < Time.current }

就是这样!您现在可以在视图中使用 @past@future。如果事件确实是 ActiveRecord 模型,您可以更进一步并将其添加到 Event class:

def past?
  self.time < Time.current
end

然后按如下方式更改您的控制器:

(@past, @future) = events.partition(&:past?)
# equivalent to the following:
# (@past, @future) = events.partition { |event| event.past? }

如果您需要跨一系列控制器执行此操作并且想要封装您不需要单独模块的功能,只需在您的 ApplicationController 中定义一个函数以供每个控制器调用。

# application_controller.rb
def prepare_events(events)
  (@past, @future) = events.partition { |event| event.time < Time.current }
  events
end

# widgets_controller.rb
def index
  @widgets = Widget.all
  prepare_events(@widgets)
end

如果无论集合的内容如何,​​您总是填充相同的实例变量,您甚至可以在应用程序控制器中将其设为 after_filter:

after_filter :prepare_events
def prepare_events
  (@past, @future) = @resources.partition { |event| event.time < Time.current }
  true
end

为了能够多次添加事件,您需要加入数组。最简单的方法是将它们添加并再次拆分。

# application_controller.rb
def prepare_events(events)
  events = events + @past + @future if @past
  (@past, @future) = events.uniq.partition { |event| event.time < Time.current }
  true
end