Я разрабатываю движок для использования в ряде других приложений. Он предоставляет некоторые основные функции Player
и Action
для приложений, использующих концепции геймификации.
В движке есть модель Player
с базовыми атрибутами и методами, которые я тестировал отдельно (с RSpec) и все работает само по себе. Я интегрирую движок с другим приложением, и все функции по умолчанию в порядке, но когда я пытаюсь расширить модель приложения Player
дополнительными атрибутами, они попадают в базу данных, но недоступны из класс Руби. Я подозреваю, что проблема связана с тем, что классы Player
имеют одинаковое имя и что класс приложения наследуется от класса Engine, но я не могу понять точную проблему и как ее исправить.
Объяснение /код следует:
Файлы движка
Класс игрока 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
Схема проигрывателя Engine:
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
Файлы приложения
config/initializers/core_engine.rb
CoreEngine.player_class = "Player"
Я правильно включил гем core_engine (здесь не показан)
Класс 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
Обратите внимание, что energy
и credits
присутствуют. Я также проверил, что они находятся в реальной таблице Postgres через psql
:
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
, но я не понимаю, в чем проблема. Я могу определить методы в модели Player
приложения, которые оно может вызывать, а также методы в модели Player
движка, которые могут вызывать оба, но не атрибуты, подобные этому.
Я полагаю, что потенциально мог бы использовать явные методы для доступа к этим определенно существующим столбцам базы данных, но я бы предпочел, чтобы я мог просто использовать Rails/ActiveRecord, как обычно.
Это мой первый опыт работы с двигателями (первый пост тоже!), и до сих пор все было очень позитивно. Мы будем очень признательны за любую помощь!