Skip to content
Andrew Geweke edited this page Nov 2, 2013 · 4 revisions

Although some of the options you can pass to is_low_card_table or has_low_card_table are documented elsewhere as well, it's very useful to have them all together in a single page.

has_low_card_table

For example:

class User < ActiveRecord::Base
  has_low_card_table :status, :delegate => { :except => [ :gender ] }, :prefix => 'foo', :foreign_key => :my_random_key, :class => SomeStatusClass
end
  • :delegate: If nil, no methods will be created in this class that delegate to the low-card table at all. If an Array, only methods matching those strings/symbols will be created. If a Hash, must contain a single key, :except, which maps to an Array; all methods except those methods will be created. Not specifying :delegate causes it to delegate all methods in the low-card table.
  • :prefix: If true, then delegated methods will be named with a prefix of the association name — for example, status_deleted, status_donation_level, and so on. If a string or symbol, then delegated methods will be named with that prefix — for example, foo_deleted, foo_donation_level, and so on. Not specifying :prefix is the same as saying :prefix => nil, which causes methods not to be prefixed with anything.
  • :foreign_key: Specifies the column in the referring table that contains the foreign key to the low-card table, just as in ActiveRecord associations. If not specified, it defaults to #{self.name.underscore}_#{association_name}_id — for example, user_status_id.
  • :class: Specifies the model class of the low-card table, as a string, symbol, or Class object. If not specified, defaults to ("#{self.name.underscore.singularize}_#{association_name}".camelize.constantize) — for example, UserStatus.

Note that the behavior of the last two options is different from ActiveRecord behavior intentionally: low-card tables are almost always "owned" by just one referring table, and thus it makes sense to name them with the name of the referring table as well as their own name, rather than just their own name. You can use these options to easily override this with traditional ActiveRecord naming, if you prefer.

is_low_card_table

For example:

class UserStatus < ActiveRecord::Base
  is_low_card_table :exclude_column_names => [ :last_manually_verified_at ]
end
  • :exclude_column_names: Specifies an Array of column names that are not to be treated as attributes of the low-card table — they are excluded from the unique index, not delegated to by referring tables, and so on; they are just ordinary columns. created_at and updated_at are automatically treated this way, so that you can safely use them on low-card tables just fine.
  • :max_row_count: When loading the cache, low_card_tables will raise an error if it finds too many rows in the table. (It actually does a LIMIT on its maximum-row-count plus one, so, even if there are ten billion rows in the table for some awful reason, it won't exhaust RAM.) By default, this limit is 5,000 rows as a rule of thumb. You can change this with :max_row_count; there is no inherent limit — but remember that you will have n ActiveRecord models in RAM forever if you have n rows in the table.

Migrations

For example:

create_table :foo, :low_card => true do |t|
  ...
end
add_column :foo, :bar, :integer, :low_card => true
remove_column :foo, :bar, :low_card_collapse_rows => false
change_table :foo, :low_card => true do |t|
  ...
end
  • :low_card: This option is necessary only if your migration code, for whatever reason, does not find a model declaring is_low_card_table that maps to the table you're changing. (The migration code eagerly loads all Rails classes, so it should find the model class if it's there.) It never hurts to add it, though. (However, don't add it to a statement changing a table that isn't low-card — you'll get a unique index that you really don't want!)

For remove_column only, additional options are documented in Migrations.

Clone this wiki locally