Instantly share code, notes, and snippets.

Embed
What would you like to do?
Make it more test-ish
unless File.exist?('Gemfile')
File.write('Gemfile', <<-GEMFILE)
source 'https://rubygems.org'
gem 'rails', :github => 'rails/rails'
gem 'sqlite3'
GEMFILE
system 'bundle'
end
require 'bundler'
Bundler.setup(:default)
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)
# Define a DB schema for the test we would run
ActiveRecord::Schema.define do
create_table :people do |t|
t.string :name
end
create_table :computers do |t|
end
create_table :accounts do |t|
t.belongs_to :person
t.belongs_to :computer
t.string :role # Given that role is nil we can leverage
end
end
# The person, a real object
class Person < ActiveRecord::Base
# Every computer that person has access to
has_many :accounts
has_many :computers, :through => :accounts
# Only comps that this account can administrate
has_many :administrator_accounts, :class_name => 'Account::Administrator'
has_many :administrated_computers, :through => :administrator_accounts, :source => :computer
end
# The account - a relationship (<3) between a person and a computer
class Account < ActiveRecord::Base
belongs_to :person
belongs_to :computer
# The administrator subclass - here we're using a `default_scope` rather than just normal STI with a `type` field (which I prefer)
class Administrator < Account
default_scope lambda { where(:role => 'administrator') }
end
end
# The computer being used
class Computer < ActiveRecord::Base
# [ALL] Users
has_many :accounts
has_many :people, :through => :accounts
# Administrators through abnormal accounts
has_many :administrator_accounts, :class_name => 'Account::Administrator'
has_many :administrators, :through => :administrator_accounts, :source => :person
end
# The test
describe Account, 'The tests' do
before do
@person1 = Person.create
@person2 = Person.create
@comp1 = Computer.create
@comp2 = Computer.create
@person1.computers << @comp1
@person1.administrated_computers << @comp2
@person2.computers << @comp2
@person2.administrated_computers << @comp1
end
after do
Person.destroy_all
Computer.destroy_all
end
it 'Person#1 should have access to all computers' do
@person1.computers.to_a.sort!.must_equal [@comp1, @comp2]
end
it 'Person#1 should administrate only Computer#2' do
@person1.administrated_computers.to_a.must_equal [@comp2]
end
it 'Person#2 should have access to all computers' do
@person2.computers.to_a.sort!.must_equal [@comp1, @comp2]
end
it 'Person#2 should administrate only Computer#1' do
@person2.administrated_computers.to_a.must_equal [@comp1]
end
end
@ka8725

This comment has been minimized.

ka8725 commented Nov 21, 2013

Good point. Idea about sti replacement looks rather interesting. Thanks for sharing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment