Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
markgandolfo committed Jan 16, 2010
0 parents commit 4509b17
Show file tree
Hide file tree
Showing 18 changed files with 8,948 additions and 0 deletions.
20 changes: 20 additions & 0 deletions MIT-LICENSE
@@ -0,0 +1,20 @@
Copyright (c) 2010 Mark Gandolfo

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48 changes: 48 additions & 0 deletions README.markdown
@@ -0,0 +1,48 @@
Associated With
============

In most of my rails applications I need to check if a certain object is associated with another object.
I usually do this the long way, so I finally decided to create a plugin for a project I'm working on called [Scrum&Cola](http://scrumandcola.com)

Example
=======

Ok, first you'll need ActiveRecord classes, with associations.

class Post < ActiveRecord::Base
belongs_to :author
end

class Author < ActiveRecord::Base
has_many :posts
end

Next find a post, and an author.

post = Post.find(1)
author = Author.find(1)

Now lets see if they're associated.

post.associated_with? author

or I can do it the other way around

author.associated_with? post


This will return a true or false!

Tests
=====

To run the tests, create a database `associated_with_test` and simply just into the plugin's directory and type `rake`


TODO
====

I still have to write tests for polymorphic relationships, but i've "tested" manually and it works fine.. expect them up soon.


Copyright (c) 2010 Mark Gandolfo, released under the MIT license
24 changes: 24 additions & 0 deletions Rakefile
@@ -0,0 +1,24 @@
require 'spec/rake/spectask'
require 'rake/rdoctask'

desc 'Default: run unit tests.'
task :default => :spec

desc 'Test the associated with plugin.'
Spec::Rake::SpecTask.new(:spec) do |t|
t.libs << 'lib'
t.verbose = true
end


desc 'Generate documentation for the associated_with plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'AssociatedWith'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end



Binary file added associated_with.sqlite3
Binary file not shown.
1 change: 1 addition & 0 deletions init.rb
@@ -0,0 +1 @@
require 'associated_with'
1 change: 1 addition & 0 deletions install.rb
@@ -0,0 +1 @@
# Install hook code here
18 changes: 18 additions & 0 deletions lib/associated_with.rb
@@ -0,0 +1,18 @@
module AssociatedWith
def associated_with? object
class_name = object.class.to_s.downcase

if self.respond_to?(class_name.pluralize)
association = class_name.pluralize
return self.__send__(association).include?(object)
elsif self.respond_to?(class_name.singularize)
association = class_name.singularize
return self.__send__(association) == object
else
return false
end

end
end

ActiveRecord::Base.send :include, AssociatedWith
120 changes: 120 additions & 0 deletions spec/associated_with_spec.rb
@@ -0,0 +1,120 @@
require 'spec_helper'

describe Task do

context "test if no association is present between the two objects" do
it "should return false if no association exists" do
programmer = Factory(:programmer)
task = Factory(:task)

task.associated_with?(programmer).should eql(false)
end
end

context "has_one association (programmer -> computer)" do
it "should return false if object 1 is not associated with an object2" do
programmer1 = Factory(:programmer)
computer1 = Factory(:computer, :programmer_id => programmer1.id)
programmer2 = Factory(:programmer)
computer2 = Factory(:computer, :programmer_id => programmer2.id)

programmer1.associated_with?(computer2).should eql(false)
programmer2.associated_with?(computer1).should eql(false)
end

it "should return true if object1 is associated with object2" do
programmer = Factory(:programmer)
computer = Factory(:computer, :programmer_id => programmer.id)
programmer.associated_with?(computer).should eql(true)
end
end

context "belongs_to associations (task -> project)" do
it "should return false if object 1 is not associated with an object2" do
project1 = Factory(:project)
task1 = Factory(:task, :project_id => project1.id)
project2 = Factory(:project)
task2 = Factory(:task, :project_id => project2.id)

task1.associated_with?(project2).should eql(false)
task2.associated_with?(project1).should eql(false)
end

it "should return true if object1 is associated with object2" do
project = Factory(:project)
task = Factory(:task, :project_id => project.id)

task.associated_with?(project).should eql(true)
end
end

context "has_many associations (project -> tasks)" do
it "should return false if object 1 is not associated with an object2" do
project1 = Factory(:project)
task1 = Factory(:task, :project_id => project1.id)
project2 = Factory(:project)
task2 = Factory(:task, :project_id => project2.id)

project1.associated_with?(task2).should eql(false)
project2.associated_with?(task1).should eql(false)
end

it "should return true if object1 is associated with object2" do
project = Factory(:project)
task = Factory(:task, :project_id => project.id)

project.associated_with?(task).should eql(true)
end
end

context "has_and_belongs_to_many associations (programmer -> project)" do
it "should return false if object 1 is not associated with an object2" do
project1 = Factory(:project)
programmer1 = Factory(:programmer)
project1.programmers << programmer1

project2 = Factory(:project)
programmer2 = Factory(:programmer)
project2.programmers << programmer2

project1.associated_with?(programmer2).should eql(false)
project2.associated_with?(programmer1).should eql(false)
end

it "should return true if object1 is associated with object2" do
project = Factory(:project)
programmer = Factory(:programmer)
project.programmers << programmer

project.associated_with?(programmer).should eql(true)
end
end

context "has_many through associations (analyst -> document_store -> document)" do
it "should return false if object 1 is not associated with an object2" do
analyst1 = Factory(:analyst)
document1 = Factory(:document)
analyst1.documents << document1

analyst2 = Factory(:analyst)
document2 = Factory(:document)
analyst2.documents << document2

analyst1.associated_with?(document2).should eql(false)
analyst2.associated_with?(document1).should eql(false)
document1.associated_with?(analyst2).should eql(false)
document2.associated_with?(analyst1).should eql(false)
end

it "should return true if object1 is associated with object2" do
analyst = Factory(:analyst)
document = Factory(:document)
analyst.documents << document

analyst.associated_with?(document).should eql(true)
document.associated_with?(analyst).should eql(true)
end
end

## TODO test polymorphic
end
9 changes: 9 additions & 0 deletions spec/database.yml
@@ -0,0 +1,9 @@
mysql:
username: root
password:
database: associated_with
adapter: mysql

sqlite3:
adapter: sqlite3
database: associated_with.sqlite3
31 changes: 31 additions & 0 deletions spec/factories.rb
@@ -0,0 +1,31 @@
Factory.define(:analyst) do |f|
f.sequence(:name) { |n| "Name#{n}"}
end

Factory.define(:computer) do |f|
f.sequence(:name) { |n| "Name#{n}"}
f.programmer_id {|a| a.association(:programmer) }
end

Factory.define(:document) do |f|
f.sequence(:name) { |n| "Name#{n}"}
end

Factory.define(:document_store) do |f|
f.sequence(:name) { |n| "Name#{n}"}
f.document_id {|a| a.association(:document) }
f.analyst_id {|a| a.association(:analyst) }
end

Factory.define(:programmer) do |f|
f.sequence(:name) { |n| "Name#{n}"}
end

Factory.define(:project) do |f|
f.sequence(:name) { |n| "Name#{n}"}
end

Factory.define(:task) do |f|
f.sequence(:name) { |n| "Name#{n}"}
f.project_id {|a| a.association(:project) }
end
33 changes: 33 additions & 0 deletions spec/fixtures/models.rb
@@ -0,0 +1,33 @@
class Analyst < ActiveRecord::Base
has_many :document_stores
has_many :documents, :through => :document_stores
end

class Computer < ActiveRecord::Base
belongs_to :programmer
end

class Document < ActiveRecord::Base
has_many :document_stores
has_many :analysts, :through => :document_stores
end

class DocumentStore < ActiveRecord::Base
belongs_to :document
belongs_to :analyst
end

class Programmer < ActiveRecord::Base
has_and_belongs_to_many :projects
has_one :computer
end

class Project < ActiveRecord::Base
has_and_belongs_to_many :programmers
has_many :tasks
end

class Task < ActiveRecord::Base
belongs_to :project
end

55 changes: 55 additions & 0 deletions spec/fixtures/schema.rb
@@ -0,0 +1,55 @@
ActiveRecord::Schema.define do
self.verbose = false

create_table "analysts", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "computers", :force => true do |t|
t.string "name"
t.integer "programmer_id"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "document_stores", :force => true do |t|
t.string "name"
t.integer "document_id"
t.integer "analyst_id"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "documents", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "programmers", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "projects", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "programmers_projects", :force => true, :id => false do |t|
t.string "project_id"
t.string "programmer_id"
end

create_table "tasks", :force => true do |t|
t.string "name"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
end

end
2 changes: 2 additions & 0 deletions spec/rcov.opts
@@ -0,0 +1,2 @@
--exclude "spec/*,gems/*"
--rails
4 changes: 4 additions & 0 deletions spec/spec.opts
@@ -0,0 +1,4 @@
--colour
--format progress
--loadby mtime
--reverse

0 comments on commit 4509b17

Please sign in to comment.