README in joinfix-0.1.1 vs README in joinfix-1.0.0

- old
+ new

@@ -1,86 +1,158 @@ -# = JoinFix -# A reflection-based solution to the fixture join problem. -# -# == Info -# -# Copyright (c) 2006-2007, Regents of the University of Colorado. -# Developer:: Simon Chiang, Biomolecular Structure Program -# Support:: UCHSC School of Medicine Deans Academic Enrichment Fund -# Licence:: MIT-Style -# -# == Usage -# Consider the following data model: -# -# class User < ActiveRecord::Base -# has_many :user_groups, -# has_many :groups, :through => :user_groups -# end -# -# class Group < ActiveRecord::Base -# has_many :group_users, :class_name => 'UserGroup' -# has_many :users, :through => :group_users -# end -# -# class UserGroup < ActiveRecord::Base -# belongs_to :user -# belongs_to :group -# end -# -# Write your fixtures using the naming scheme you lay out in your models. -# Entries can be spread across multiple fixture files, or not. Joins between -# entries are written inline, either by referening the name of another entry -# or by defining the joined entry: -# -# [users.yml] -# bob: -# login: bob -# groups: admin_group # => reference to the 'admin_group' entry -# -# jane: -# id: 3 # => you can specify ids if you want -# login: jane -# groups: # => an array of joins -# - admin_group -# - workers: -# name: worker bees -# -# samantha: -# login: sam -# groups: # => inline definition of joined entries -# movers: -# name: movers -# shakers: -# name: shakers -# -# [groups.yml] -# admin_group: # => references can span files -# name: administrators -# -# Join entries implied in your definition, as in a has_and_belongs_to_many association, will -# be created and named by joining together the names of the parent and child, ordered -# by the '<' operator. For example, the users.yml and groups.yml fixtures will also produce: -# -# admin_group_bob # => join for bob and admin_group -# jane_workers # => join for jane and workers -# ... -# -# In your tests, require joinfix and use the fixtures exactly as you would normally. -# One gotcha (which really isn't a gotcha) -- you must be sure to name all the tables -# for which your fixtures create entries. In fact this is no different than normal, -# but it's easy to forget if you lump joins into one file. -# -# require 'joinfix' -# -# class UserTest < Test::Unit::TestCase -# fixtures :users, :groups, :user_groups # => got to name them all! -# -# def test_joinfix -# assert_equal "administrators", users(:bob).groups.first.name -# assert_equal 2, User.find_by_login("jane").groups.count -# assert_equal 3, UserGroup.find(user_groups(:jane_workers).id).user.id -# assert_equal users(:samantha), User.find_by_login("sam").groups.find_by_name("movers").users.first -# end -# end -# -# += JoinFix +A reflection-based solution to the fixture join problem. +== Description +Making fixtures for models with complex joins can be a redundant, error-prone process. JoinFix +provides a solution to this problem by letting you reference and/or define child entries inline with +their parents. + + [users.yml] + john_doe: + full_name: John Doe + groups: + - admin_group # => entry reference + - devel_group: # => inline definition + name: Developers + + [groups.yml] + admin_group: # => referenced entry + name: Administrators + +JoinFix uses reflection on ActiveRecord associations to determine how to perform joins so +no configuration is required. Simply require joinfix and begin writing entries. + +== Info + +Available at {rubyforge.org/projects/joinfix}[http://rubyforge.org/projects/joinfix] + +Copyright (c) 2006-2007, Regents of the University of Colorado. +Developer:: Simon Chiang, Biomolecular Structure Program +Support:: UCHSC School of Medicine Deans Academic Enrichment Fund +Licence:: MIT-Style + +== Usage +Consider the following data model: + + class User < ActiveRecord::Base + has_many :user_groups + has_many :groups, :through => :user_groups + end + + class Group < ActiveRecord::Base + has_many :user_groups + has_many :users, :through => :user_groups + end + + class UserGroup < ActiveRecord::Base + belongs_to :user + belongs_to :group + end + +Write your fixtures using the naming scheme you lay out in your models. +Entries can be referenced across multiple fixture files or defined inline: + + [users.yml] + john_doe: + full_name: John Doe + groups: admin_group # => reference to the 'admin_group' entry + + jane_doe: + full_name: Jane Doe + groups: # => you can specify an array of entries if needed + - admin_group + - worker_group: # => inline definition of the 'worker_group' entry + name: Workers + + [groups.yml] + admin_group: # => the referenced 'admin_group' entry + id: 3 # => you can (but don't have to) specify ids + name: Administrators + +Join entries implied in your definition, as in a has_and_belongs_to_many association, +will be created and named by joining together the names of the parent and child, +ordered by the '<' operator. For example, the users.yml and groups.yml fixtures +produce these entries: + + [users] + john_doe: + id: 1 # => primary keys are assigned to all entries (see note) + full_name: John Doe + jane_doe: + id: 2 + full_name: Jane Doe + + [groups] + admin_group: + id: 3 + name: Administrators + worker_group: + id: 1 + name: Workers + + [user_groups] + admin_group_john_doe + id: 1 + user_id: 1 # => references are resolved to their foreign keys + group_id: 3 # => explicitly set primary keys are respected + admin_group_jane_doe + id: 2 + user_id: 2 + group_id: 3 + jane_doe_worker_group # => Notice the '<' operator in action + id: 3 + user_id: 2 + group_id: 1 + +Note: Primary keys are assigned to entries based on the way the entry names are hashed, ie 'john_doe' will not necessarily have id '1'. If you need a specific id for an entry, then you must explicitly set it. + +If you need to add additional fields to an implied entry, simply define them in their +fixture file. All fields across all fixtures will be merged into one entry (JoinFix raises +an error in the event of a collision). + + [user_groups.yml] + admin_group_john_doe: + date_added: 2007-06-12 + +Nesting is allowed. This will make the same entries as above: + + [users.yml] + john_doe: + full_name: John Doe + groups: + admin_group: + id: 3 + name: Administrators + users: + jane_doe: + full_name: Jane Doe + groups: + worker_group: + name: Workers + +In your tests, require joinfix and use the fixtures exactly as you would normally. +One gotcha -- you must be sure to name all the tables for which your fixtures create entries. +In fact this is no different than normal, but it's easy to forget if you lump joins into one file. + + require 'joinfix' + + class UserTest < Test::Unit::TestCase + fixtures :users, :groups, :user_groups # => got to name them all!!! + + def test_joinfix + assert_equal "Administrators", users(:john_doe).groups.first.name + assert_equal 2, User.find_by_full_name("jane_doe").groups.count + assert_equal 3, UserGroup.find(user_groups(:admin_group_jane_doe).id).group.id + end + end + +=== Command line options + +JoinFix provides some command line options through the ENV variables. Setting these +variables is easy if you're using rake[http://rake.rubyforge.org/] to run your test suite: + + % rake test key=value # => sets ENV['key'] = 'value' + +Available options: + +format_joinfix_errors:: Unless 'false', this option causes JoinFix to simplify the console output when a JoinFixError occurs. +joinfix_dump:: Prints all entries for tables matching joinfix_dump to STDOUT upon make_join_fixtures. Prints entries for all tables if 'true'.