Skip to content
Open
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
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ jobs:
- rails: "7.2"
ruby: "3.1"
env:
RAILS_ENV: test
RAILS_VERSION: ${{ matrix.rails }}

name: ${{ format('rails-{0} ruby-{1}', matrix.rails, matrix.ruby) }}
Expand All @@ -39,6 +38,8 @@ jobs:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true

- run: bin/rails db:prepare

- name: Parallel Tests
run: bin/rails test

Expand Down
39 changes: 38 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,44 @@ You can convert your Rails fixtures to Oaken's seeds by running:
bin/rails generate oaken:convert:fixtures
```

This will convert anything in test/fixtures to db/seeds. E.g. `test/fixtures/users.yml` becomes `db/seeds/users.rb` and so on.
This will convert anything in test/fixtures to db/seeds. E.g. `test/fixtures/users.yml` becomes `db/seeds/test/users.rb` and so on.

#### Accessing Oaken seeds from fixtures

Call `grant_fixture_access` to make Oaken seeds accessible from fixtures:

```ruby
# db/seeds/test/setup.rb
grant_fixture_access accounts, users
```

> [!TIP]
> Since fixtures are a test environment thing, place this in the test-environment dedicated setup in `db/seeds/test/setup.rb`.

```ruby
# db/seeds/test/accounts.rb
accounts.create :kaspers_donuts, name: "Kasper's Donuts"
accounts.create name: "Demo" # Inaccessible! Pass a label ala `:kaspers_donuts` above to access this record from fixtures.

# You can also use `accounts.label` to expose records in fixtures.
accounts.label demo: Account.find_by!(name: "Demo")
```

Now you can access the created record from fixtures:

```yaml
# test/fixtures/menus.yml
basic_kasper_menu:
name: "Kasper's Basic Menu"
account: kaspers_donuts

basic_demo_menu:
name: "Demo's Basic Menu"
account: demo
```

> [!WARNING]
> Fixtures truncate data per table before inserting any anything. This means if you have say `test/fixtures/menus.yml`, you can't have any menus in Oaken seeds. So you have to port by file and then every fixture in a file. So convert every fixture in e.g. `test/fixtures/menus.yml` at once.

#### Disable fixtures

Expand Down
25 changes: 25 additions & 0 deletions lib/oaken/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,29 @@ def self.respond_to_missing?(meth, ...) = loader.locate(meth) || super
# end
# end
def self.section(*, **) = block_given? && yield

# Make any labelled records accessible in Rails' fixtures. Useful when porting from fixtures to Oaken.
#
# grant_fixture_access accounts
#
# # Now passing the label `:kaspers_donuts` here makes this record accessible:
# accounts.create :kaspers_donuts, name: "Kasper's Donuts"
#
# # test/fixtures/menus.yml
# basic:
# name: "Basic Menu"
# account: kaspers_donuts # We're accessing the named record by the label here.
def self.grant_fixture_access(*registers)
registers.each { _1.extend FixtureAccess }
end

module FixtureAccess
def create(label = nil, id: identify(label), **) = super
def upsert(label = nil, id: identify(label), **) = super

private
def identify(label)
ActiveRecord::FixtureSet.identify(label) if label
end
end
end
3 changes: 3 additions & 0 deletions test/dummy/app/models/account/fixture_access.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Account::FixtureAccess < ApplicationRecord
belongs_to :account
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CreateAccountFixtureAccesses < ActiveRecord::Migration[8.0]
def change
create_table :account_fixture_accesses do |t|
t.references :account, null: false, index: true
t.string :name

t.timestamps
end
end
end
10 changes: 9 additions & 1 deletion test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2025_10_24_125945) do
ActiveRecord::Schema[8.0].define(version: 2025_11_02_174456) do
create_table "account_fixture_accesses", force: :cascade do |t|
t.integer "account_id", null: false
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["account_id"], name: "index_account_fixture_accesses_on_account_id"
end

create_table "accounts", id: :string, default: -> { "ULID()" }, force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
Expand Down
1 change: 1 addition & 0 deletions test/dummy/db/seeds/test/setup.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
grant_fixture_access accounts
3 changes: 3 additions & 0 deletions test/dummy/test/fixtures/account/fixture_accesses.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
basic:
name: "Basic Access"
account: kaspers_donuts
5 changes: 5 additions & 0 deletions test/dummy/test/models/oaken_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ class OakenTest < ActiveSupport::TestCase
assert_equal [users.kasper, users.coworker], accounts.kaspers_donuts.users
end

test "accessing fixture from within rails fixtures" do
assert_equal 1, Account::FixtureAccess.count
assert_equal accounts.kaspers_donuts, Account::FixtureAccess.first.account
end

test "accessing fixture from test env" do
assert plans.test_premium
end
Expand Down
1 change: 1 addition & 0 deletions test/dummy/test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ class ActiveSupport::TestCase
parallelize workers: :number_of_processors, threshold: ENV.fetch("PARALLEL_TEST_THRESHOLD", 5).to_i

include Oaken.test_setup
fixtures "account/fixture_accesses"
end
Loading