The following based on Myers' original paper.
To use the example from the paper, say you want to calculate the difference between two strings:
The following based on Myers' original paper.
To use the example from the paper, say you want to calculate the difference between two strings:
| # Wouldn't it be great if you could have STI like functionality | |
| # without needing to encode strings of class names in the database? | |
| # Well today is your lucky day! Discriminable Model is here to help. | |
| # | |
| # Simply specify your models desired type column, and provide a block to | |
| # do the discrimination. If you want the whole STI-esque shebang of properly | |
| # typed finder methods you can supply an array of 'discriminate_types' that will | |
| # be used to apply an appropriate type. | |
| # | |
| # class MyModel < ActiveRecord::Base |
| # speed up pluck | |
| class ActiveRecord::Relation | |
| class RailsDateTimeDecoder < PG::SimpleDecoder | |
| def decode(string, tuple=nil, field=nil) | |
| if Rails.version >= "4.2.0" | |
| @caster ||= ActiveRecord::Type::DateTime.new | |
| @caster.type_cast_from_database(string) | |
| else |
I'm going to describe a weird problem I faced when using ActiveRecord today. To protect the innocent, I'm not going to talk about the app I'm actually working on but will instead discuss a hypothetical but isomorphic database design for a clone of the popular blogging platform Tumblr.
Tumblr lets you publish various different sorts of content. We might be tempted to shove all these types in a big STI table, but the types are all quite different from one another and so we give them their own tables.
| # | |
| # PostgreSQL writes two optional commands to the database schema | |
| # file, called db/structure.sql, that can only be run as a root | |
| # database user. These are not needed actually, so comment them | |
| # out automatically | |
| # | |
| # CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; | |
| # COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; | |
| # | |
| namespace :db do |
| #!/usr/bin/env ruby | |
| class Module | |
| private | |
| def delegate(*args) | |
| dest, prefix = _extract_valid_delegation_options(args.pop) | |
| _define_delegators(caller_locations.first, prefix, dest, args) | |
| end |
| # use inverse_of to 'just work' | |
| class User < ActiveRecord::Base | |
| has_many :contributions, inverse_of: :user | |
| has_many :posts, through: :contributions | |
| end | |
|  | |
| class Post < ActiveRecord::Base | |
| has_many :contributions, inverse_of: :post | |
| has_many :contributors, through: :contributions, | |
| source: :user |
| #!/usr/bin/env ruby | |
| # thin init script | |
| # install to /etc/init.d/thin | |
| # crazy debian LSB header stuff | |
| ### BEGIN INIT INFO | |
| # Provides: thin | |
| # Required-Start: $local_fs $remote_fs | |
| # Required-Stop: $local_fs $remote_fs |