Skip to content

Instantly share code, notes, and snippets.

@stv8
Created February 25, 2025 03:45
Rails `after_create` <> `has_many through` weirdness
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "rails"
# If you want to test against edge Rails replace the previous line with this:
# gem "rails", github: "rails/rails", branch: "main"
gem "sqlite3"
end
require "active_record/railtie"
require "minitest/autorun"
# This connection will do for database-independent bug reports.
ENV["DATABASE_URL"] = "sqlite3::memory:"
class TestApp < Rails::Application
config.load_defaults Rails::VERSION::STRING.to_f
config.eager_load = false
config.logger = Logger.new($stdout)
config.secret_key_base = "secret_key_base"
config.active_record.encryption.primary_key = "primary_key"
config.active_record.encryption.deterministic_key = "deterministic_key"
config.active_record.encryption.key_derivation_salt = "key_derivation_salt"
end
Rails.application.initialize!
ActiveRecord::Schema.define do
create_table :users do |t|
t.text :name
end
create_table :roles do |t|
t.text :title
end
create_table :user_roles do |t|
t.belongs_to :user
t.belongs_to :role
t.index [:user_id, :role_id], unique: true
end
end
class User < ActiveRecord::Base
# placing assign_default_role here causes unique constraint errors
after_create :assign_default_role
has_many :user_roles
has_many :roles, through: :user_roles
# placing assign_default_role here works for unknown-to-me reasons
# after_create :assign_default_role
def assign_default_role
role = Role.first
roles << role
end
end
class Role < ActiveRecord::Base
has_many :user_roles
has_many :users, through: :user_roles
end
class UserRole < ActiveRecord::Base
belongs_to :user
belongs_to :role
end
class BugTest < ActiveSupport::TestCase
def test_association_stuff
role = Role.create!(title: "admin")
user = User.create!(name: "Derpman")
assert_equal 1, user.roles.count
assert_equal user.id, role.users.first.id
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment