diff options
| author | mo khan <mo@mokhan.ca> | 2014-07-12 13:47:30 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2014-07-12 13:47:30 -0600 |
| commit | 9d11dbbb3053811be6fd54407e08b5119c9756b3 (patch) | |
| tree | dd216287acb0eb63f396b0ad757082a09fb107ff | |
| parent | 8d4e52f369a1571b5745f83d028a2d3b3c7ec268 (diff) | |
load a has_many relationship.
| -rw-r--r-- | lib/humble/column.rb | 22 | ||||
| -rw-r--r-- | lib/humble/database_table.rb | 4 | ||||
| -rw-r--r-- | lib/humble/mapping_configuration.rb | 14 | ||||
| -rw-r--r-- | lib/humble/mapping_configuration_builder.rb | 4 | ||||
| -rw-r--r-- | lib/humble/session.rb | 4 | ||||
| -rw-r--r-- | spec/integration/fixtures/movie_mapping.rb | 3 | ||||
| -rw-r--r-- | spec/integration/fixtures/review_mapping.rb | 13 | ||||
| -rw-r--r-- | spec/integration/select_spec.rb | 12 | ||||
| -rw-r--r-- | spec/integration_helper.rb | 9 |
9 files changed, 69 insertions, 16 deletions
diff --git a/lib/humble/column.rb b/lib/humble/column.rb index a7d6ec2..66ab233 100644 --- a/lib/humble/column.rb +++ b/lib/humble/column.rb @@ -15,7 +15,8 @@ module Humble @column_name == column_name end - def apply(value, entity, session) + def apply(row, entity, session) + value = row[column_name] entity.public_send("#{@column_name}=", value) end @@ -51,7 +52,8 @@ module Humble @type = type end - def apply(value, entity, session) + def apply(row, entity, session) + value = row[column_name] entity.public_send("#{attribute_name}=", session.find(@type, value)) end @@ -65,4 +67,20 @@ module Humble column_name.to_s.gsub(/_id/, '') end end + + class HasMany < Column + def initialize(attribute, type) + super(attribute) + @attribute, @type = attribute, type + end + + def apply(row, entity, session) + items = session.find_all(@type) + entity.public_send("#{@attribute}=", items) + end + + def prepare(entity) + { } + end + end end diff --git a/lib/humble/database_table.rb b/lib/humble/database_table.rb index bb3dc07..63090ea 100644 --- a/lib/humble/database_table.rb +++ b/lib/humble/database_table.rb @@ -32,10 +32,6 @@ module Humble end end - def column_for(key) - @columns.find { |x| x.matches?(key) } - end - def prepare_statement_for(item) @columns.inject({}) do |result, column| result.merge(column.prepare(item)) diff --git a/lib/humble/mapping_configuration.rb b/lib/humble/mapping_configuration.rb index 3b57f04..f70c97b 100644 --- a/lib/humble/mapping_configuration.rb +++ b/lib/humble/mapping_configuration.rb @@ -12,8 +12,8 @@ module Humble def save_using(session, entity) connection = session.create_connection[@table.name] if primary_key.has_default_value?(entity) - result = connection.insert(@table.prepare_statement_for(entity)) - primary_key.apply(result, entity, session) + connection.insert(@table.prepare_statement_for(entity)) + primary_key.apply(connection, entity, session) else connection.update(@table.prepare_statement_for(entity)) end @@ -40,17 +40,19 @@ module Humble end class DefaultMapper + attr_reader :session, :table + def initialize(table, session) @table = table @session = session end def map_from(row) - @table.type.new.tap do |entity| - row.each do |key, value| - @table.column_for(key).apply(value, entity, @session) - end + entity = table.type.new + table.each do |column| + column.apply(row, entity, session) end + entity end end end diff --git a/lib/humble/mapping_configuration_builder.rb b/lib/humble/mapping_configuration_builder.rb index 3e95699..b8b1e37 100644 --- a/lib/humble/mapping_configuration_builder.rb +++ b/lib/humble/mapping_configuration_builder.rb @@ -20,6 +20,10 @@ module Humble @table.add(BelongsTo.new(foreign_key, type)) end + def has_many(attribute_name, type) + @table.add(HasMany.new(attribute_name, type)) + end + def build(mapping) @table = DatabaseTable.new mapping.run(self) diff --git a/lib/humble/session.rb b/lib/humble/session.rb index e09e88e..936aa39 100644 --- a/lib/humble/session.rb +++ b/lib/humble/session.rb @@ -16,7 +16,9 @@ module Humble end def find(clazz, id) - find_all(clazz).find { |x| x.id == id } + find_all(clazz).find do |x| + x.id == id + end end def find_all(clazz) diff --git a/spec/integration/fixtures/movie_mapping.rb b/spec/integration/fixtures/movie_mapping.rb index 5056bf9..8e6bcb7 100644 --- a/spec/integration/fixtures/movie_mapping.rb +++ b/spec/integration/fixtures/movie_mapping.rb @@ -1,5 +1,5 @@ class Movie - attr_accessor :id, :name, :studio + attr_accessor :id, :name, :studio, :reviews def ==(other) return false unless other @@ -16,5 +16,6 @@ class MovieMapping < Humble::DatabaseMapping map.primary_key(:id, default: -1) map.column :name map.belongs_to :studio_id, Studio + map.has_many :reviews, Review end end diff --git a/spec/integration/fixtures/review_mapping.rb b/spec/integration/fixtures/review_mapping.rb new file mode 100644 index 0000000..709f5ab --- /dev/null +++ b/spec/integration/fixtures/review_mapping.rb @@ -0,0 +1,13 @@ +class Review + attr_accessor :id, :description, :movie +end + +class ReviewMapping < Humble::DatabaseMapping + def run(map) + map.table :reviews + map.type Review + map.primary_key(:id, default: -1) + map.column :description + map.belongs_to :movie_id, Movie + end +end diff --git a/spec/integration/select_spec.rb b/spec/integration/select_spec.rb index 41848e1..058fb84 100644 --- a/spec/integration/select_spec.rb +++ b/spec/integration/select_spec.rb @@ -5,7 +5,7 @@ describe "select items" do context "when fetching all items" do before :each do - @id = connection[:movies].insert(:name => 'monsters inc') + @id = connection[:movies].insert(name: 'monsters inc') end let(:results) { session.find_all Movie } @@ -32,6 +32,11 @@ describe "select items" do let!(:studio_id) { connection[:studios].insert(name: 'universal') } let!(:movie_id) { connection[:movies].insert(name: 'blood in, blood out', studio_id: studio_id) } let(:result) { session.find(Movie, movie_id) } + let(:description) { 'wow... that snail is fast.' } + + before :each do + connection[:reviews].insert(movie_id: movie_id, description: description) + end it "loads the proper type" do expect(result).to be_instance_of(Movie) @@ -50,7 +55,10 @@ describe "select items" do expect(result.studio.name).to eql('universal') end - xit "loads the has_many association" do + it "loads a has_many association" do + expect(result.reviews).to_not be_nil + expect(result.reviews.first.description).to eql(description) + expect(result.reviews.first.description).to eql(description) end end end diff --git a/spec/integration_helper.rb b/spec/integration_helper.rb index 868eaf5..3ec5123 100644 --- a/spec/integration_helper.rb +++ b/spec/integration_helper.rb @@ -2,6 +2,7 @@ require "spec_helper" require 'sequel' require_relative 'integration/fixtures/studio_mapping.rb' require_relative 'integration/fixtures/movie_mapping.rb' +require_relative 'integration/fixtures/review_mapping.rb' shared_context "orm" do let(:connection) { Sequel.connect(connection_string) } @@ -22,12 +23,20 @@ shared_context "orm" do String :name end + connection.create_table :reviews do + primary_key :id + BigNum :movie_id + String :description + end + configuration.add(MovieMapping.new) configuration.add(StudioMapping.new) + configuration.add(ReviewMapping.new) end after :each do connection.drop_table :studios connection.drop_table :movies + connection.drop_table :reviews end end |
