引擎和应用程序具有相同的类名 - 无法向App的类添加属性

时间:2014-10-23 19:07:47

标签: ruby-on-rails ruby ruby-on-rails-4 rails-engines

我正在开发一种在许多其他应用程序中使用的引擎。它为使用游戏化概念的应用提供了一些核心PlayerAction功能。

引擎有一个带有基本属性和方法的Player模型,我已经单独测试过(使用RSpec),一切都在自行完成。我正在将引擎与另一个应用程序集成,并且所有默认功能都可以,但是当我尝试使用其他属性扩展 App的 Player模型时,它们会进入数据库,但不是无法从Ruby类访问。 我怀疑这个问题与Player类具有相同名称并且App的类继承Engine类的事实有关,但我无法弄清楚确切的问题以及如何解决它。
解释/代码如下:

引擎文件

引擎的玩家类:

module CoreEngine
  class Player < ActiveRecord::Base
    belongs_to :user, class_name: CoreEngine.user_class
    has_many :player_actions

    def add_action(some_action)
      self.player_actions.create(action: some_action)
    end

    def add_actions(array_of_actions)
      array_of_actions.each do |action|
        self.add_action(action)
      end
    end

    def total_score
      self.player_actions.sum(:points_earned)
    end
  end
end

引擎的播放器架构:

create_table "core_engine_players", force: true do |t|
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string   "name"
  t.integer  "user_id"
end

LIB / core_engine / engine.rb

module CoreEngine
  class Engine < ::Rails::Engine
    isolate_namespace CoreEngine

    config.generators do |g|
      g.test_framework      :rspec,        :fixture => false
      g.fixture_replacement :factory_girl, :dir => 'spec/factories'
      g.assets false
      g.helper false
    end
  end
end

LIB / core_engine.rb

require "core_engine/engine"

module CoreEngine
  mattr_accessor :player_class
  mattr_accessor :action_class
  mattr_accessor :user_class

  def self.root
    File.expand_path(File.dirname(File.dirname(__FILE__)))
  end

  def self.models_dir
    "#{root}/app/models/core_engine/"
  end

  def self.controllers_dir
    "#{root}/app/controllers/core_engine/"
  end
end

应用程序文件

配置/初始化/ core_engine.rb

CoreEngine.player_class = "Player"

我已正确包含core_engine gem(此处未显示)

App的Player类(注意它是从引擎继承的):

class Player < CoreEngine::Player
end

应用的播放器架构

  create_table "players", force: true do |t|
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "user_id"
    t.integer  "energy"
    t.integer  "credits"
  end

请注意,energycredits存在。我还通过psql验证了它们在实际的Postgres表中:

                                     Table "public.players"
   Column   |            Type             |                      Modifiers                       
------------+-----------------------------+------------------------------------------------------
 id         | integer                     | not null default nextval('players_id_seq'::regclass)
 created_at | timestamp without time zone | 
 updated_at | timestamp without time zone | 
 user_id    | integer                     | 
 energy     | integer                     | 
 credits    | integer                     | 
Indexes:
    "players_pkey" PRIMARY KEY, btree (id)

我没有收到任何迁移错误。然而,当我运行rails控制台并致电Player时,我得到:

2.1.1p76 :001 > Player
 => Player(id: integer, created_at: datetime, updated_at: datetime, name: string, user_id: integer)

在任何地方都找不到energy。我确定它与继承引擎的Player模型有关,但我不知道实际问题是什么。我可以在App的Player模型中定义它可以调用的方法,以及引擎的Player模型中两者可以调用的方法,但不能像这个。

我想我可能会使用显式方法来访问那些肯定存在的数据库列,但如果我像往常一样只使用Rails / ActiveRecord,我会更喜欢它。

这是我第一次使用引擎的体验(也是第一篇文章!)到目前为止,一切都非常积极。任何帮助都将非常感谢!

1 个答案:

答案 0 :(得分:1)

可能是,玩家模型指向引擎表。通过Player.table_name在Rails控制台中查看它。如果它是core_engine_players,只需在app Player类

中覆盖它

&#13;
&#13;
class Player
  self.table_name = 'players'
end
&#13;
&#13;
&#13;