Skip to content

Commit

Permalink
Fixes #35 (potentially), virtuals should work now on initialization.
Browse files Browse the repository at this point in the history
  • Loading branch information
Travis Reeder committed Jul 6, 2011
1 parent 9ed5b45 commit 20be220
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 58 deletions.
2 changes: 1 addition & 1 deletion lib/simple_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ def initialize(attrs={})
def initialize_base(attrs={})

#we have to handle the virtuals.
Attributes.handle_virtuals(attrs)
handle_virtuals(attrs)

clear_errors

Expand Down
89 changes: 48 additions & 41 deletions lib/simple_record/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ def has_attributes2(args, options_for_all={})
attr = Attribute.new(type, arg_options)
defined_attributes[arg] = attr if defined_attributes[arg].nil?

# define reader method
# define reader method
arg_s = arg.to_s # to get rid of all the to_s calls
send(:define_method, arg) do
ret = get_attribute(arg)
return ret
end

# define writer method
# define writer method
send(:define_method, arg_s+"=") do |value|
set(arg, value)
end
Expand All @@ -81,13 +81,13 @@ def define_dirty_methods(arg_s)
@dirty.has_key?(sdb_att_name(arg_s))
end

# define change method
# define change method
send(:define_method, arg_s + "_change") do
old_val = @dirty[sdb_att_name(arg_s)]
[old_val, get_attribute(arg_s)]
end

# define was method
# define was method
send(:define_method, arg_s + "_was") do
old_val = @dirty[sdb_att_name(arg_s)]
old_val
Expand Down Expand Up @@ -149,51 +149,56 @@ def has_clobs(*args)

end

def virtuals
@virtuals ||= []
@virtuals
end

def has_virtuals(*args)
@@virtuals = args
virtuals.concat(args)
args.each do |arg|
#we just create the accessor functions here, the actual instance variable is created during initialize
attr_accessor(arg)
end
end

# One belongs_to association per call. Call multiple times if there are more than one.
#
# This method will also create an {association)_id method that will return the ID of the foreign object
# without actually materializing it.
#
# options:
# :class_name=>"User" - to change the default class to use
# One belongs_to association per call. Call multiple times if there are more than one.
#
# This method will also create an {association)_id method that will return the ID of the foreign object
# without actually materializing it.
#
# options:
# :class_name=>"User" - to change the default class to use
def belongs_to(association_id, options = {})
arg = association_id
arg_s = arg.to_s
arg_id = arg.to_s + '_id'
attribute = Attribute.new(:belongs_to, options)
defined_attributes[arg] = attribute

# todo: should also handle foreign_key http://74.125.95.132/search?q=cache:KqLkxuXiBBQJ:wiki.rubyonrails.org/rails/show/belongs_to+rails+belongs_to&hl=en&ct=clnk&cd=1&gl=us
# puts "arg_id=#{arg}_id"
# puts "is defined? " + eval("(defined? #{arg}_id)").to_s
# puts 'atts=' + @attributes.inspect
# todo: should also handle foreign_key http://74.125.95.132/search?q=cache:KqLkxuXiBBQJ:wiki.rubyonrails.org/rails/show/belongs_to+rails+belongs_to&hl=en&ct=clnk&cd=1&gl=us
# puts "arg_id=#{arg}_id"
# puts "is defined? " + eval("(defined? #{arg}_id)").to_s
# puts 'atts=' + @attributes.inspect

# Define reader method
# Define reader method
send(:define_method, arg) do
return get_attribute(arg)
end


# Define writer method
# Define writer method
send(:define_method, arg.to_s + "=") do |value|
set(arg, value)
end


# Define ID reader method for reading the associated objects id without getting the entire object
# Define ID reader method for reading the associated objects id without getting the entire object
send(:define_method, arg_id) do
get_attribute_sdb(arg_s)
end

# Define writer method for setting the _id directly without the associated object
# Define writer method for setting the _id directly without the associated object
send(:define_method, arg_id + "=") do |value|
# rb_att_name = arg_s # n2 = name.to_s[0, name.length-3]
set(arg_id, value)
Expand Down Expand Up @@ -237,14 +242,16 @@ def has_one(*args)

end

@@virtuals=[]

def self.handle_virtuals(attrs)
@@virtuals.each do |virtual|
#we first copy the information for the virtual to an instance variable of the same name
eval("@#{virtual}=attrs['#{virtual}']")
#and then remove the parameter before it is passed to initialize, so that it is NOT sent to SimpleDB
eval("attrs.delete('#{virtual}')")
def handle_virtuals(attrs)
puts 'handle_virtuals'
self.class.virtuals.each do |virtual|
puts 'virtual=' + virtual.inspect
#we first copy the information for the virtual to an instance variable of the same name
send("#{virtual}=", attrs[virtual])
#eval("@#{virtual}=attrs['#{virtual}']")
#and then remove the parameter before it is passed to initialize, so that it is NOT sent to SimpleDB
attrs.delete(virtual)
#eval("attrs.delete('#{virtual}')")
end
end

Expand Down Expand Up @@ -289,17 +296,17 @@ def set(name, value, dirtify=true)
attname = name.to_s
attvalue = att_meta.init_value(value)
# attvalue = value
#puts 'converted ' + value.inspect + ' to ' + attvalue.inspect
#puts 'converted ' + value.inspect + ' to ' + attvalue.inspect
end
end
attvalue = strip_array(attvalue)
make_dirty(name, attvalue) if dirtify
# puts "ARG=#{attname.to_s} setting to #{attvalue}"
# puts "ARG=#{attname.to_s} setting to #{attvalue}"
sdb_val = ruby_to_sdb(name, attvalue)
# puts "sdb_val=" + sdb_val.to_s
# puts "sdb_val=" + sdb_val.to_s
@attributes[attname] = sdb_val
# attvalue = wrap_if_required(name, attvalue, sdb_val)
# puts 'attvalue2=' + attvalue.to_s
# attvalue = wrap_if_required(name, attvalue, sdb_val)
# puts 'attvalue2=' + attvalue.to_s

if store_rb_val
@attributes_rb[name.to_s] = value
Expand All @@ -321,11 +328,11 @@ def get_attribute_sdb(name)
return ret
end

# Since SimpleDB supports multiple attributes per value, the values are an array.
# This method will return the value unwrapped if it's the only, otherwise it will return the array.
# Since SimpleDB supports multiple attributes per value, the values are an array.
# This method will return the value unwrapped if it's the only, otherwise it will return the array.
def get_attribute(name)
# puts "get_attribute #{name}"
# Check if this arg is already converted
# Check if this arg is already converted
name_s = name.to_s
name = name.to_sym
att_meta = get_att_meta(name)
Expand All @@ -340,7 +347,7 @@ def get_attribute(name)
return ret
end
end
# get it from s3
# get it from s3
unless new_record?
if self.class.get_sr_config[:single_clob]
begin
Expand All @@ -362,7 +369,7 @@ def get_attribute(name)
else
begin
ret = s3_bucket.get(s3_lob_id(name))
# puts 'got from s3 ' + ret.inspect
# puts 'got from s3 ' + ret.inspect
SimpleRecord.stats.s3_gets += 1
rescue Aws::AwsError => ex
if ex.include?(/NoSuchKey/) || ex.include?(/NoSuchBucket/)
Expand All @@ -386,9 +393,9 @@ def get_attribute(name)
return ret unless ret.nil?
return nil if ret.is_a? RemoteNil
ret = get_attribute_sdb(name)
# p ret
# p ret
ret = sdb_to_ruby(name, ret)
# p ret
# p ret
@attributes_rb[name_s] = ret
return ret
end
Expand All @@ -404,7 +411,7 @@ def set_attributes(atts)
end


# Holds information about an attribute
# Holds information about an attribute
class Attribute
attr_accessor :type, :options

Expand Down
6 changes: 4 additions & 2 deletions test/my_base_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

class MyBaseModel < SimpleRecord::Base

has_strings :base_string
has_strings :base_string

has_virtuals :v1



end
1 change: 0 additions & 1 deletion test/test_simple_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

class TestSimpleRecord < TestBase


def test_save_get
mm = MyModel.new
mm.name = "Travis"
Expand Down
17 changes: 4 additions & 13 deletions test/test_temp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,10 @@

class TestSimpleRecord < TestBase

def test_custom_id
puts 'test_custom_id...'
custom_id = "id-travis"
mm = MyModel.new
mm.id = custom_id
mm.name = "Travis"
mm.age = 32
mm.cool = true
mm.save
sleep 1
mm2 = MyModel.find(custom_id)
puts 'mm2=' + mm2.inspect
assert mm2.id == mm.id
def test_virtuals
model = MyBaseModel.new(:v1=>'abc', :base_string=>'what')
assert model.v1 == 'abc', "model.v1=" + model.v1.inspect

end

end

0 comments on commit 20be220

Please sign in to comment.