Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,41 @@ jobs:
bundler-cache: true
- name: Run RuboCop
run: bundle exec rubocop
test:
runs-on: ubuntu-latest
timeout-minutes: 20
env:
BUNDLE_PATH: vendor/bundle
strategy:
fail-fast: false
matrix:
ruby:
- "3.2"
- "3.3"
- "3.4"
appraisal:
- rails-7_0
- rails-7_1
- rails-7_2
- rails-8_0
- rails-8_1
steps:
- uses: actions/checkout@v6

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true

- name: Install system deps
run: sudo apt-get update && sudo apt-get install -y libsqlite3-dev pkg-config

- name: Install Appraisal gemfiles
run: bundle exec appraisal install

- name: Run specs (${{ matrix.appraisal }})
run: bundle exec appraisal ${{ matrix.appraisal }} rspec spec

- name: Run rails sample specs (${{ matrix.appraisal }})
run: bundle exec appraisal ${{ matrix.appraisal }} rake rails_sample_spec
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/tmp/
/.bundle/
/vendor/bundle/
/Gemfile.lock
/gemfiles/*.gemfile.lock
/.idea/
/pkg
*.lock
*.gem
64 changes: 64 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
AllCops:
DisplayCopNames: true
NewCops: enable
SuggestExtensions: false

plugins:
- rubocop-rspec
- rubocop-performance
- rubocop-rails
- rubocop-rspec_rails
- rubocop-factory_bot

### Lint ###
Lint/AmbiguousOperatorPrecedence:
Expand Down Expand Up @@ -143,3 +149,61 @@ Metrics/ModuleLength:

Metrics/PerceivedComplexity:
Enabled: false

### Rails ###
Rails:
Enabled: true

Rails/Blank:
Enabled: false

Rails/Delegate:
Enabled: false

Rails/Output:
Enabled: false

Rails/SquishedSQLHeredocs:
Enabled: false

Rails/RedundantActiveRecordAllMethod:
Enabled: false

Rails/DynamicFindBy:
AllowedMethods:
- find_by_id
- find_by_id!
- find_by_ids
- find_by_ids!

Rails/InverseOf:
Enabled: false

Rails/HasManyOrHasOneDependent:
Enabled: false

Rails/I18nLocaleTexts:
Enabled: false

Rails/FindEach:
Enabled: false

### Performance ###
Performance/CollectionLiteralInLoop:
Enabled: false

### RSpec ###
RSpec/MultipleExpectations:
Enabled: false

RSpec/ExampleLength:
Enabled: false

RSpec/DescribeClass:
Enabled: false

RSpec/MultipleMemoizedHelpers:
Enabled: false

RSpec/LetSetup:
Enabled: false
13 changes: 13 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

rails_versions = ENV.fetch("RAILS_VERSIONS", "7.0 7.1 7.2 8.0 8.1").split

rails_versions.each do |version|
appraise "rails-#{version.tr('.', '_')}" do
gem "rails", "~> #{version}"
gem "sqlite3", "~> 2.1"
gem "rspec"
gem "factory_bot"
gem "puma"
end
end
14 changes: 14 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,18 @@ source "https://rubygems.org"

gemspec

gem "factory_bot", group: :test
gem "puma", group: :development
gem "rails", ENV.fetch("RAILS_VERSION", "~> 7.2"), group: :development

gem "rspec", group: :test
gem "rubocop", group: :development
gem 'rubocop-factory_bot', group: :development
gem 'rubocop-performance', group: :development
gem 'rubocop-rails', group: :development
gem 'rubocop-rspec', group: :development
gem 'rubocop-rspec_rails', group: :development
gem "sqlite3", "~> 2.1", group: :development

gem "appraisal", group: :development
gem "rake", group: :development
89 changes: 0 additions & 89 deletions Gemfile.lock

This file was deleted.

12 changes: 12 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

require "bundler/setup"
require "rspec/core/rake_task"

RSpec::Core::RakeTask.new(:spec)
RSpec::Core::RakeTask.new(:rails_sample_spec) do |task|
task.pattern = "examples/rails_sample/spec/**/*_spec.rb"
task.rspec_opts = "--require ./examples/rails_sample/spec/spec_helper --default-path examples/rails_sample/spec"
end

task default: :spec
19 changes: 19 additions & 0 deletions examples/rails_sample/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/log/
/tmp/
/db/*.sqlite3
/db/*.sqlite3-*
/db/*.sqlite3-journal
/db/*.sqlite3-wal
/db/*.sqlite3-shm
/storage/
/node_modules/
/vendor/bundle/
/.bundle/
/.byebug_history
/coverage/
/public/assets/
/public/packs/
/public/packs-test/
/public/webpack/
/yarn-error.log
/npm-debug.log
106 changes: 106 additions & 0 deletions examples/rails_sample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Rails Sample App

This sample app demonstrates SimpleMaster in a compact, game-like domain.
It is used to exercise column casting and association patterns (STI, polymorphic
`belongs_to`, `has_many`).

## Development Setup
```bash
bundle install
cd examples/rails_sample
bundle exec rails db:prepare
bundle exec rails s
```

## Database Configuration
Database settings live in `examples/rails_sample/config/database.yml`.

- `development`: sqlite3 at `examples/rails_sample/db/development.sqlite3`
- `test`: sqlite3 in-memory (`:memory:`)
- `production`: sqlite3 at `examples/rails_sample/db/production.sqlite3`

If you need a different DB, edit `config/database.yml` or set `DATABASE_URL`.

## Domain Model
```
SimpleMaster (masters) ActiveRecord

[Weapon] (STI: Gun, Blade) [Player] --< player_items >-- (polymorphic to Weapon/Armor/Potion)
[Armor] PlayerItem: belongs_to :item, polymorphic
[Potion]
[Level] --< players (lv) >-- [Player]
[Enemy] --< rewards >-- [Reward] (reward_type/reward_id -> Weapon/Armor/Potion)
```

## Masters
- **Weapon** (`Gun`, `Blade`)
- `id`
- `type`
- `name`
- `attack` (float)
- `info` (json, symbolize_names: true)
- `metadata` (json, symbolize_names: false)
- `rarity` (enum)
- `flags` (bitmask)
- Notes: polymorphic target (PlayerItem, Reward)
- **Armor**
- `id`
- `name`
- `defence` (float)
- Notes: polymorphic target
- **Potion**
- `id`
- `name`
- `hp` (float)
- Notes: polymorphic target
- **Level**
- `id`
- `lv` (unique)
- `attack` (float)
- `defence` (float)
- `hp` (float)
- Associations: `has_many :players` (lv)
- **Enemy**
- `id`
- `name`
- `is_boss` (boolean)
- `start_at` (time)
- `end_at` (time)
- `attack`
- `defence`
- `hp`
- Associations: `has_many :rewards`
- **Reward**
- `id`
- `enemy_id`
- `reward_type`
- `reward_id`
- Associations: `belongs_to :enemy`; polymorphic `belongs_to` Weapon/Armor/Potion

## ActiveRecord
- **Player**
- `id`
- `name`
- `lv`
- Associations: `belongs_to :level` (lv); `has_many :player_items`; `has_many :items, through: :player_items`
- **PlayerItem**
- `player_id`
- `item_type`
- `item_id`
- Associations: `belongs_to :player`; polymorphic `belongs_to :item`

## Fixtures
Fixtures live in `examples/rails_sample/fixtures/masters`.

- `weapons.json` (STI Gun/Blade), `armors.json`, `potions.json`, `levels.json` (uses `lv` as unique key),
`enemies.json`, `rewards.json`
- Aim to include representative casts (float/json/globalize where useful) and polymorphic/has_many links.

## Related Specs
- `simple_master/active_record/extension_spec.rb`: AR↔master (`belongs_to_master`)
- `simple_master/master/item_spec.rb`: column casting and master associations
- `simple_master/master/filterable_spec.rb`: find/find_by/all_by/all_in
- `simple_master/master/cache_spec.rb`: cache_method, cache_class_method
- `simple_master/storage/loader_spec.rb`: STI instantiation, diff application
- `simple_master/loader/marshal_loader_spec.rb`: Marshal dump/load roundtrip
- `simple_master/storage/dataset_spec.rb`: dataset cache/diff duplication
5 changes: 5 additions & 0 deletions examples/rails_sample/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

require_relative "config/application"

Rails.application.load_tasks
Loading