README.md in has_dynamic_columns-0.1.1 vs README.md in has_dynamic_columns-0.2.0
- old
+ new
@@ -1,15 +1,15 @@
has_dynamic_columns
============
-Add dynamic columns to ActiveRecord models
+This plugin gives ActiveRecord models the ability to dynamically define collectable data based on ***has_many*** and ***belongs_to*** relationships.
Installation
============
```ruby
-gem 'has_dynamic_columns', :git => 'git://github.com/butchmarshall/has_dynamic_columns.git'
+gem "has_dynamic_columns"
```
The Active Record migration is required to create the has_dynamic_columns table. You can create that table by
running the following command:
@@ -17,23 +17,172 @@
rake db:migrate
Usage
============
+has_dynamic_columns
+
+ - as:
+ - the setter/getter method
+ - field_scope:
+ - **belongs_to** or **has_many** relationship
+
+## **belongs_to** relationship
+
+Our example is a data model where an **account** ***has_many*** **customers** and each **customer** ***has_many*** **customer_addresses**
+
+Each customers collectable info is uniquely defined by the associated account.
+
+Each customer addresses collectable info is defined by the associated customers account.
+
+**Models**
```ruby
class Account < ActiveRecord::Base
has_many :customers
has_dynamic_columns
end
class Customer < ActiveRecord::Base
belongs_to :account
- has_many :customer_addresses
- has_dynamic_columns field_scope: "account", as: "fields"
+ has_dynamic_columns field_scope: "account", as: "customer_fields"
end
class CustomerAddress < ActiveRecord::Base
belongs_to :customer
has_dynamic_columns field_scope: "customer.account"
end
```
+**Setup**
+```ruby
+# ------------------------------------------------
+# Create our first account
+# ------------------------------------------------
+account = Account.new(:name => "Account #1")
+
+# Define a first_name field
+account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "first_name", :data_type => "string")
+# Define a last_name field
+account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "last_name", :data_type => "string")
+# Define a company field
+account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "company", :data_type => "string")
+
+# save
+account.save
+
+# ------------------------------------------------
+# Create our second account
+# ------------------------------------------------
+account = Account.new(:name => "Account #2")
+
+# Define a first_name field
+account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "first_name", :data_type => "string")
+# Define a last_name field
+account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "last_name", :data_type => "string")
+# Define a country field
+account.activerecord_dynamic_columns.build(:dynamic_type => "Customer", :key => "country", :data_type => "string")
+
+# save
+account.save
+```
+
+**Data**
+```ruby
+# Add a customer to our first account
+account = Account.find(1)
+customer = Customer.new(:account => account)
+customer.customer_fields = {
+ "first_name" => "Butch",
+ "last_Name" => "Marshall",
+ "company" => "Aperture Science"
+}
+customer.save
+
+# as_json
+customer.as_json
+# == { "id": 1, "account_id": 1, "customer_fields" => { "first_name" => "Butch", "last_Name" => "Marshall", "company" => "Aperture Science" } }
+
+# Add a customer to our first account
+account = Account.find(1)
+customer = Customer.new(:account => account)
+customer.customer_fields = {
+ "first_name" => "John",
+ "last_Name" => "Paterson",
+ "company" => "Aperture Science"
+}
+customer.save
+
+# Add a customer to our second account
+account = Account.find(2)
+customer = Customer.new(:account => account)
+customer.customer_fields = {
+ "first_name" => "Butch",
+ "last_Name" => "Marshall",
+ "country" => "Canada"
+}
+customer.save
+
+# as_json
+puts customer.as_json
+# == { "id": 2, "account_id": 2, "customer_fields" => { "first_name" => "Butch", "last_Name" => "Marshall", "country" => "Canada" } }
+```
+
+**Searching**
+```ruby
+
+# ------------------------------------------------
+# with_scope
+# ------------------------------------------------
+
+# ------------------------------------------------
+# Find customers under the first account
+# ------------------------------------------------
+account = Account.find(1)
+
+# 1 result
+Customer.where.has_dynamic_scope({ :first_name => "Butch" }).with_scope(account)
+
+# 1 result
+Customer.where.has_dynamic_scope({ :first_name => "Butch", :company => "Aperture Science" }).with_scope(account)
+
+# 0 results
+Customer.where.has_dynamic_scope({ :first_name => "Butch", :company => "Blaaaaa" }).with_scope(account)
+
+# 2 results
+Customer.where.has_dynamic_scope({ :company => "Aperture Science" }).with_scope(account)
+
+# ------------------------------------------------
+# Find customers under the second account
+# ------------------------------------------------
+account = Account.find(2)
+# 1 result
+Customer.where.has_dynamic_scope({ :first_name => "Butch" }).with_scope(account)
+
+# 1 result
+Customer.where.has_dynamic_scope({ :first_name => "Butch", :country => "Canada" }).with_scope(account)
+
+# 0 results
+Customer.where.has_dynamic_scope({ :first_name => "Butch", :country => "Japan" }).with_scope(account)
+```
+
+# ------------------------------------------------
+# without_scope
+# ------------------------------------------------
+
+# 6 results
+# finds everyone named butch, no matter what account they're apart of
+Customer.where.has_dynamic_scope({ :first_name => "Butch" }).without_scope
+
+# ------------------------------------------------
+# with Arel
+# WARNING: compound conditionals such as Customer.arel_table[:first_Name].matches("B%").and(Customer.arel_table[:first_Name].eq("Canada")) are NOT currently supported
+# ------------------------------------------------
+
+# 6 matches
+Customer.where.has_dynamic_scope(Customer.arel_table[:first_Name].matches("B%")).without_scope
+
+# 1 match
+Customer.where.has_dynamic_scope(Customer.arel_table[:first_Name].eq("Canada")).with_scope(Account.find(1))
+
+## **has_many** relationship
+
+TODO example.
\ No newline at end of file