Skip to content

Instantly share code, notes, and snippets.

@rob-murray
Last active August 29, 2015 14:07
Show Gist options
  • Save rob-murray/5823eca2d05e3a5c19f5 to your computer and use it in GitHub Desktop.
Save rob-murray/5823eca2d05e3a5c19f5 to your computer and use it in GitHub Desktop.
Rails ActiveRecord #composed_of macro
# == Schema Information
#
# Table name: blocks
#
# id :integer not null, primary key
# name :string(255)
# content :text
# type :string(255)
# created_at :datetime
# updated_at :datetime
#
class Block < ActiveRecord::Base; end
# == Schema Information
#
# Table name: blocks
#
# id :integer not null, primary key
# name :string(255)
# content :text
# type :string(255)
# created_at :datetime
# updated_at :datetime
#
class DateBlock < Block
# Define a virtual attribute ':date' that maps to the real ':content' field
# which is then serialized when persisted. Form fields are set up using
# the :date attr but front end content call :content or :date, both
# return a Date object.
composed_of :date,
class_name: 'Date',
mapping: %w(content to_date),
constructor: Proc.new { |date| date }
serialize :content
end
2.1.3 :033 > block = Block.new
=> #<Block id: nil, name: nil, content: nil, type: nil, created_at: nil, updated_at: nil>
2.1.3 :034 > block.content
=> nil
2.1.3 :035 > block.content = Date.today
=> Tue, 21 Oct 2014
2.1.3 :036 > block.save
(0.2ms) begin transaction
SQL (1.3ms) INSERT INTO "blocks" ("content", "created_at", "updated_at") VALUES (?, ?, ?) [["content", "2014-10-21"], ["created_at", "2014-10-21 20:33:10.755853"], ["updated_at", "2014-10-21 20:33:10.755853"]]
(1.0ms) commit transaction
=> true
2.1.3 :037 > block.reload
Block Load (0.4ms) SELECT "blocks".* FROM "blocks" WHERE "blocks"."id" = ? LIMIT 1 [["id", 5]]
=> #<Block id: 5, name: nil, content: "2014-10-21", type: nil, created_at: "2014-10-21 20:33:10", updated_at: "2014-10-21 20:33:10">
2.1.3 :038 > block.content
=> "2014-10-21"
2.1.3 :039 > block.content.class
=> String
2.1.3 :040 > block.content < Date.today + 1.day
ArgumentError: comparison of String with Date failed
2.1.3 :071 > block = DateBlock.new
=> #<DateBlock id: nil, name: nil, content: nil, type: "DateBlock", created_at: nil, updated_at: nil>
2.1.3 :072 > block.content
=> nil
2.1.3 :073 > block.date
=> nil
2.1.3 :074 > block.date = Date.today
=> Tue, 21 Oct 2014
2.1.3 :075 > block.save
(0.1ms) begin transaction
SQL (0.5ms) INSERT INTO "blocks" ("content", "created_at", "type", "updated_at") VALUES (?, ?, ?, ?) [["content", "--- 2014-10-21\n...\n"], ["created_at", "2014-10-21 20:37:24.481074"], ["type", "DateBlock"], ["updated_at", "2014-10-21 20:37:24.481074"]]
(0.8ms) commit transaction
=> true
2.1.3 :076 > block.content
=> Tue, 21 Oct 2014
2.1.3 :077 > block.date
=> Tue, 21 Oct 2014
2.1.3 :078 > block.date.class
=> Date
2.1.3 :079 > block.content.class
=> Date
2.1.3 :080 >
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment