Cells-4.0.4:未初始化的常量 Cell::Concept (NameError)

Cells-4.0.4 : uninitialized constant Cell::Concept (NameError)

环境:

CentOS-6.7 / OSX-10.9.5
Ruby 2.2.3p173
Rails 4.2.5.1
Trailblazer 1.1.0

我正在研究 Trailblazer 书中的示例,将它们映射到当前项目。直到我从 ActionView 切换到 Cells 时,我的工作或多或少都符合预期。我将模板移至 app/concepts/ar_invoice/views 并创建了 app/concepts/ar_invoice/cell.rb。在我启动 rails server 时进行此更改后出现此错误:

app/concepts/ar_invoice/cell.rb:1:in `<top (required)>': 
  uninitialized constant Cell::Concept (NameError)

涉及的代码是这样的:

宝石文件:

Gems included by the bundle:
  * ISO3166P2 (0.0.1)
  * actionmailer (4.2.5.1)
  * actionpack (4.2.5.1)
  * actionview (4.2.5.1)
  * activejob (4.2.5.1)
  * activemodel (4.2.5.1)
  * activerecord (4.2.5.1)
  * activesupport (4.2.5.1)
  * addressable (2.4.0)
  * annotate (2.7.0)
  * ansi (1.5.0)
  * arel (6.0.3)
  * autoprefixer-rails (6.3.1)
  * axiom-types (0.1.1)
  * bcrypt (3.1.10)
  * bootstrap-sass (3.3.6)
  * bootstrap3-datetimepicker-rails (4.17.37)
  * builder (3.2.2)
  * bundler (1.11.2)
  * byebug (8.2.2)
  * capistrano (3.4.0)
  * capistrano-bundler (1.1.4)
  * capistrano-rails (1.1.6)
  * capybara (2.6.2)
  * cells (4.0.4)
  * cells-hamlit (0.1.1)
  * coercible (1.0.0)
  * coffee-rails (4.1.1)
  * coffee-script (2.4.1)
  * coffee-script-source (1.10.0)
  * concurrent-ruby (1.0.0)
  * cucumber (2.3.2)
  * cucumber-core (1.4.0)
  * cucumber-rails (1.4.3)
  * cucumber-wire (0.0.1)
  * daemons (1.2.3)
  * database_cleaner (1.5.1)
  * debug_inspector (0.0.2)
  * declarative (0.0.5)
  * declarative_authorization (0.5.7)
  * descendants_tracker (0.0.4)
  * devise (3.5.6)
  * devise-encryptable (0.2.0)
  * devise_security_extension (0.9.2)
  * diff-lcs (1.2.5)
  * disposable (0.2.5)
  * equalizer (0.0.11)
  * erubis (2.7.0)
  * eventmachine (1.0.9.1)
  * execjs (2.6.0)
  * gherkin (3.2.0)
  * globalid (0.3.6)
  * hamlit (2.2.1)
  * hamlit-block (0.3.0)
  * hamlit-rails (0.1.0)
  * humanize (1.1.0)
  * i18n (0.7.0)
  * ice_nine (0.11.2)
  * jbuilder (2.4.0)
  * jquery-rails (4.1.0)
  * json (1.8.3)
  * loofah (2.0.3)
  * mail (2.6.3)
  * mime-types (2.99)
  * mini_portile2 (2.0.0)
  * minitest (5.8.4)
  * minitest-capybara (0.7.2)
  * minitest-metadata (0.5.3)
  * minitest-rails (2.2.0)
  * minitest-rails-capybara (2.1.1)
  * minitest-reporters (1.1.7)
  * modernizr-rails (2.7.1)
  * momentjs-rails (2.11.0)
  * multi_json (1.11.2)
  * multi_test (0.1.2)
  * net-scp (1.2.1)
  * net-ssh (3.0.2)
  * nokogiri (1.6.7)
  * orm_adapter (0.5.0)
  * paper_trail (4.1.0)
  * partially_useful (0.2.2)
  * pg (0.18.4)
  * rack (1.6.4)
  * rack-test (0.6.3)
  * rails (4.2.5.1)
  * rails-deprecated_sanitizer (1.0.3)
  * rails-dom-testing (1.0.7)
  * rails-html-sanitizer (1.0.3)
  * railties (4.2.5.1)
  * rake (10.5.0)
  * rdoc (4.2.1)
  * reform (2.1.0)
  * representable (3.0.0)
  * request_store (1.3.0)
  * responders (2.1.1)
  * ruby-progressbar (1.7.5)
  * sass (3.4.21)
  * sass-rails (5.0.4)
  * sdoc (0.4.1)
  * smarter_csv (1.1.0)
  * spring (1.6.2)
  * sprockets (3.5.2)
  * sprockets-rails (3.0.1)
  * sqlite3 (1.3.10)
  * sshkit (1.8.1)
  * temple (0.7.6)
  * thin (1.6.4)
  * thor (0.19.1)
  * thread_safe (0.3.5)
  * tilt (2.0.2)
  * trailblazer (1.1.0)
  * trailblazer-loader (0.0.9)
  * trailblazer-rails (0.2.4)
  * turbolinks (2.5.3)
  * tzinfo (1.2.2)
  * uber (0.0.15)
  * uglifier (2.7.2)
  * virtus (1.0.5)
  * warden (1.2.6)
  * web-console (3.1.1)
  * xpath (2.0.0)

application.rb:

#config/application.rb
require File.expand_path('../boot', __FILE__)

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module HllThMain
  class Application < Rails::Application
    # Use the responders controller from the responders gem
    config.app_generators.scaffold_controller :responders_controller

    . . .         

    # Do not swallow errors in after_commit/after_rollback callbacks.
    config.active_record.raise_in_transactional_callbacks = true
  end
  require( "hll_th_main" )
end

# For trailBlazer
# railties have to be loaded here.

需要'trailblazer/rails/railtie'

控制器(ar_invoices_controller.rb):

class ARInvoicesController < ApplicationController
  def create
    run( ARInvoice::Create )
  end

# route => ar_invoices#new
  def new
    form( ARInvoice::Create )
  end
end

operation.rb:

class ARInvoice < GLTransaction

  class Create < Trailblazer::Operation
    include( Model )

    model( ARInvoice, :create )

    contract() do
      property( :invoice_number )
      property( :currency_code )
      property( :forex_rate )
      property( :gl_account_id )
      property( :effective_from )

      validates( :invoice_number, :presence => true )
      validates( :currency_code, :presence => true )
    end

    def process( params )
      # must use instance variable @model
      @model = ARInvoice.new
      validate( params[ :ar_invoice ], @model ) do |f|
        f.save
      end
    end
  end
end

cell.rb:

class ARInvoice::Cell < Cell::Concept

  def new()
    render
  end

  def show()
    render
  end

  private
  def body()
    model.body
  end
end

和视图 (new.haml):

= simple_form_for( @form ) do |f|
  = f.input( :invoice_number )
  = f.input( :currency_code )
  = f.input( :forex_rate )
  = f.input( :gl_account_id )

  = f.submit

我不使用任何 Trailblazer/Cells 初始值设定项。有人可以指出导致上述异常的我的错误吗?

这是一个已经投入生产的项目中与 Trailblazer 相关的部分,一些 gems 声明可能有点矫枉过正,但它确实有效:

gem "trailblazer",       "1.1.0"
gem "trailblazer-rails", ">= 0.2.3"
gem "representable",     "3.0.0"
gem "reform",            "2.1.0"
gem "reform-rails"
gem "disposable"

gem "virtus"

gem "tyrant", github: "apotonick/tyrant"

gem "cells", "4.0.3"
gem "cells-haml", "0.0.8"
gem "haml", github: "haml/haml", ref: "7c7c169"
gem "kaminari-cells"

gem "paperdragon", ">= 0.0.10"
gem "file_validators", "~> 1.2"
gem "dragonfly-s3_data_store"

gem "roar", github: "apotonick/roar"

gem "pundit"

gem "rails-timeago"
gem "email_validator"

Application.rb

require File.expand_path('../boot', __FILE__)
require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module Appname
  class Application < Rails::Application
    ...
  end
end

# railties have to be loaded here.
require 'trailblazer/rails/railtie'

Trailblazer 初始化器

require "trailblazer/operation/dispatch"
# require "trailblazer/operation/representer"
# require "trailblazer/operation/responder"

Trailblazer::Operation.class_eval do
  include Trailblazer::Operation::Dispatch
end

require "roar/json/hal"

::Roar::Representer.module_eval do
  include Rails.application.routes.url_helpers
  # include Rails.app.routes.mounted_helpers

  def default_url_options
    {}
  end
end

单元格初始化程序:

ActiveSupport::Notifications.subscribe "read_fragment.cells" do |name, start, finish, id, payload|
  Rails.logger.debug "CACHE: #{payload}"
end

ActiveSupport::Notifications.subscribe "write_fragment.cells" do |name, start, finish, id, payload|
  Rails.logger.debug "CACHE write: #{payload}"
end

你必须说 ::Cell::Concept 而不是 Cell::Concept,否则 Ruby 会在错误的命名空间中查找它。

将 gem cells 显式添加到项目 Gemfile 中解决了问题。

因为 cellscells-hamlit 的依赖项,所以我只在 Gemfile 中列出了 cells-hamlit。这确实导致 cells gem 被包含在项目中,运行 bundle list 验证了这一点。但是将 gem 加载到应用程序中是不够的。

这是 Bundler 的副作用,我以前没有意识到。