Class: BigRecord::Embedded
Overview
Embedded Records
Since a single column in a column-oriented database is perfectly suited to handle large amounts of data, BigRecord gives you the option to store entire records within a single column of another BigRecord::Base record.
These are known as Embedded records, and they behave similarly to BigRecord::Base objects, except that their data is physically stored within another BigRecord::Base record, and they don’t exist unless associated with one. Furthermore, they don’t possess any find or querying functionality.
So what are the benefits of Embedded records?
- Cleaner organization of models
- Avoids the need to create entire tables and associations for models that exist only in the context of another model.
- Allows more complicated functionality to be encompassed within an embedded record, instead of in a parent model.
All of this has been very abstract so far, therefore examples are in order.
Examples
Let’s say we start off with the following arbitrarily created models:
app/model/book.rb:
class Book < BigRecord::Base column :title, :string column :author, :string column :description, :string end
app/model/company.rb:
class Company < BigRecord::Base column :name, :string column :address, :string column :description, :string end
Now, let’s say we want the ability to create and associate weblinks with each of these models. This is a trivial modification if all we do is create a new column in each model called "weblink" (or something similar), and have a string that stores a URL.
However, what if we wanted these weblinks to have more metadata attached and more complex functionality added to it? Then our only choice is to create a new model called WebLink (for example), with its own table, set of attributes and methods. Then we have our Book and Company models associate to these newly created WebLink models, giving us something like this:
app/model/web_link.rb:
class WebLink < BigRecord::Base column :name, :string column :url, :string column :description, :string column :submitted_by, :string column :book_id, :string column :company_id, :string # Could use a polymorphic association here, of course. belongs_to_bigrecord :book, :foreign_key => "attribute:book_id" belongs_to_bigrecord :company, :foreign_key => "attribute:company_id" # other methods ... end
and likewise an association to WebLink from the Book and Company models.
Now notice the problem here? A simple concept like adding a WebLink with some metadata has increased the model logic and created some unnecessary associations. In this situation, a WebLink doesn’t need to exist except when associated to a certain model. Therefore this association should be implicit somehow.
Enter Embedded records. We will now instead define WebLink as follows:
app/model/web_link.rb:
class WebLink < BigRecord::Embedded column :name, :string column :url, :string column :description, :string column :submitted_by, :string # other methods ... end
And modify our Base records like so:
app/model/book.rb:
class Book < BigRecord::Base column :title, :string column :author, :string column :description, :string column :web_link, 'WebLink' end
app/model/company.rb:
class Company < BigRecord::Base column :name, :string column :address, :string column :description, :string column :web_link, 'WebLink' end
Now we can encompass any WebLink specific attributes and methods within the WebLink embedded class, and use them with any other Base model.
To use WebLink now, we treat it as though it were a regular model, except that we don’t execute saves on it. For example:
>> amazon_link = WebLink.new(:name => "Amazon Link to Book", :url => "http://amazon.com/some/book", :description => "Amazon sells this book for cheap!") => #<WebLink created_at: "2009-11-12 17:11:57", name: "Amazon Link to Book", url: "http://amazon.com/some/book", description: "Amazon sells this book for cheap!", submitted_by: nil, id: "2b619a68-e462-475d-8e04-01ba2aace11a"> >> amazon_link.save BigRecord::NotImplemented: BigRecord::NotImplemented # => [...] >> book = Book.find(:first) # => [...] >> book.web_link = amazon_link >> book.save
Now any subsequent access to that book object we just saved to will have a WebLink record available with it.
Constant Summary
Constants inherited from Model
ID_FIELD_SEPARATOR, ID_WHITE_SPACE_CHAR
Class Method Summary
- + (Object) base_class
-
+ (Object) connection
Borrow the default connection of BigRecord.
- + (Object) default_columns
- + (Object) hide_to_users
-
+ (Object) inherited(child)
:nodoc:.
-
+ (Object) pretty_name
Class attribute that holds the name of the embedded type for dispaly.
- + (Object) primary_key
- + (Object) set_pretty_name(new_name)
- + (Boolean) show_to_users?
- + (Boolean) store_primary_key?
Instance Method Summary
- - (Object) connection
- - (Object) id
-
- (Embedded) initialize(attrs = nil)
constructor
A new instance of Embedded.
Methods inherited from Model
#==, ===, #[], #[]=, accessible_attributes, alias_attribute, #all_attributes_loaded=, #all_attributes_loaded?, attr_accessible, attr_create_accessible, attr_protected, attr_readonly, #attribute_for_inspect, #attribute_names, #attribute_present?, #attributes, #attributes=, benchmark, column, #column_for_attribute, column_methods_hash, column_names, columns, columns_hash, content_columns, create_accessible_attributes, default_column_prefix, #deserialize, #destroy, #eql?, #freeze, #frozen?, #has_attribute?, #hash, human_attribute_name, #human_attribute_name, #id=, #inspect, instantiate, #new_record?, #preinitialize, protected_attributes, quote_value, #quoted_id, read_methods, #readonly!, #readonly?, readonly_attributes, #reload, reset_subclasses, #respond_to?, #safe_attributes=, #save, #save!, silence, #to_s, undecorated_table_name, #update_attribute, #update_attributes, #update_attributes!
Constructor Details
- (Embedded) initialize(attrs = nil)
A new instance of Embedded
128 129 130 131 132 133 |
# File 'lib/big_record/embedded.rb', line 128 def initialize(attrs = nil) super # Regenerate the id unless it's already there # (i.e. we're instantiating an existing property) @attributes["id"] ||= generate_id end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class BigRecord::Model
Class Method Details
+ (Object) base_class
165 166 167 |
# File 'lib/big_record/embedded.rb', line 165 def base_class (superclass == BigRecord::Embedded) ? self : superclass.base_class end |
+ (Object) connection
Borrow the default connection of BigRecord
161 162 163 |
# File 'lib/big_record/embedded.rb', line 161 def connection BigRecord::Base.connection end |
+ (Object) default_columns
191 192 193 |
# File 'lib/big_record/embedded.rb', line 191 def default_columns {primary_key => ConnectionAdapters::Column.new(primary_key, 'string')} end |
+ (Object) hide_to_users
178 179 180 |
# File 'lib/big_record/embedded.rb', line 178 def hide_to_users @hide_to_user = true end |
+ (Object) inherited(child)
:nodoc:
186 187 188 189 |
# File 'lib/big_record/embedded.rb', line 186 def inherited(child) #:nodoc: child.set_pretty_name child.name.split("::").last super end |
+ (Object) pretty_name
Class attribute that holds the name of the embedded type for dispaly
170 171 172 |
# File 'lib/big_record/embedded.rb', line 170 def pretty_name @pretty_name || self.to_s end |
+ (Object) primary_key
156 157 158 |
# File 'lib/big_record/embedded.rb', line 156 def primary_key "id" end |
+ (Object) set_pretty_name(new_name)
174 175 176 |
# File 'lib/big_record/embedded.rb', line 174 def set_pretty_name new_name @pretty_name = new_name end |
+ (Boolean) show_to_users?
182 183 184 |
# File 'lib/big_record/embedded.rb', line 182 def show_to_users? !@hide_to_user end |
+ (Boolean) store_primary_key?
152 153 154 |
# File 'lib/big_record/embedded.rb', line 152 def store_primary_key? true end |