Skip to content

Instantly share code, notes, and snippets.

@ta1kt0me
Last active February 26, 2024 10:49
Show Gist options
  • Save ta1kt0me/03780c83f778c8140fdb72ab9a06030c to your computer and use it in GitHub Desktop.
Save ta1kt0me/03780c83f778c8140fdb72ab9a06030c to your computer and use it in GitHub Desktop.
query_constraintsによる複合キーの関連付けの動作確認
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", "7.1.3.2"
# gem "rails", "7.1.3"
# If you want to test against edge Rails replace the previous line with this:
# gem "rails", github: "rails/rails", branch: "main"
gem "sqlite3"
gem "debug"
end
require "active_record"
require "minitest/autorun"
require "logger"
# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new($stdout)
ActiveRecord::Schema.define do
create_table :groups, force: true do |t|
t.integer :name
t.boolean :disabled, default: false
end
create_table :labels, force: true do |t|
t.integer :group_id
t.integer :label_id
end
create_table :notes, force: true do |t|
t.string :name
t.integer :group_id
t.integer :label_id
t.string :uuid
t.string :family_uuid
end
create_table :memos, force: true do |t|
t.integer :note_id
t.string :content
end
end
class Group < ActiveRecord::Base
has_many :labels, inverse_of: :group
has_many :notes, inverse_of: :group
scope :enabled, -> { where(disabled: false) }
end
class Label < ActiveRecord::Base
query_constraints :group_id, :label_id
belongs_to :group, foreign_key: :group_id, inverse_of: :labels
end
class Note < ActiveRecord::Base
query_constraints :group_id, :uuid
belongs_to :group, foreign_key: :group_id, inverse_of: :notes
belongs_to :label, query_constraints: %i[group_id label_id]
belongs_to :parent, class_name: "Note", query_constraints: %i[group_id family_uuid]
has_many :children, class_name: "Note", query_constraints: %i[group_id family_uuid]
has_many :memos, foreign_key: :id, inverse_of: :note
before_save ->(obj) { obj.uuid ||= SecureRandom.uuid }
end
class Memo < ActiveRecord::Base
belongs_to :note, foreign_key: :note_id, primary_key: :id, inverse_of: :memos
end
class BugTest < Minitest::Test
def teardown
Memo.delete_all
Note.delete_all
Label.delete_all
Group.delete_all
end
def test_association_group
group = Group.create!(name: "Group A")
group_id = group.id
label = Label.create!(group_id:, label_id: 100)
label_id = label.label_id
note = Note.create!(name: "Note Parent", group_id:, label_id:)
assert_equal group.labels, [label]
assert_equal label.group, group
assert_equal group.notes, [note]
assert_equal note.group, group
end
def test_association_label
group = Group.create!(name: "Group A")
group_id = group.id
label_id = 10
label = Label.create!(group_id:, label_id:)
Note.create!(name: "Note", group_id:, label_id:)
assert_equal label, Note.take.label
end
def test_association_parent
group = Group.create!(name: "Group A")
group_id = group.id
label_id = 1
parent = Note.create!(name: "Note Parent", group_id:, label_id:)
child = Note.create!(name: "Note Child", group_id:, label_id:, family_uuid: parent.uuid)
assert_equal parent, child.parent
assert_equal parent.children, [child]
end
def test_association_memo
group = Group.create!(name: "Group A")
group_id = group.id
label = Label.create!(group_id:, label_id: 10)
label_id = label.label_id
note = Note.create!(name: "Note", group_id:, label_id:)
note.memos.create!(content: "Memo Content")
assert_equal note.memos, [Memo.take]
assert_equal note, Memo.take.note
end
def test_joins_with_merge
group = Group.create!(name: "Group A")
group_id = group.id
label = Label.create!(group_id:, label_id: 10)
label_id = label.label_id
Note.create!(name: "Note", group_id:, label_id:)
note = Note.joins(:group).merge(Group.enabled).where(name: "Note").take
assert_equal note.name, "Note"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment