On Fri, Jan 8, 2010 at 2:41 AM, Ben Lavender <blaven...@gmail.com> wrote:
> I found myself today trying to do this, and failing:
>
> #!/usr/bin/env ruby
> require 'rubygems'
> require 'dm-core'
>
> DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/page.sqlite3")
>
> class Page
>  include DataMapper::Resource
>
>  property :id,         Serial    # primary serial key
>  property :body,       String    # cannot be null
>  property :derived1,    String
>
>  after :save, :after_save
>
>  def after_save
>      if attribute_get(:derived1).nil?
>        attribute_set(:derived1,body.to_s + ".db")
>        self.save
>      end
>  end
> end
> DataMapper.auto_migrate!
> p = Page.new({ :body => "test123" })
> p.save
> p1 = Page.get(1)
> puts p.inspect             # derived1 => body + .db
> puts p1.inspect           # derived1 => nil
>
> Initially, I was trying to make a field be a default of (item.id).to_s
> + "something", but this doesn't work with :default since attribute_get
> isn't available to the class methods defining properties.  So I came
> up with something equivalent to this, and fought it for a while.
>
> I'm working around this now just fine--it was just a naive thing for
> the first round of specs--but why does self.save not work in
> after_save here?  If it's failing on purpose (which I can imagine,
> given the risk of infinite recursion with poor programming), wouldn't
> it be better to raise an exception than to silently, magically fail?
> Perhaps at least not return true?
>
> Thanks,
> Ben
>
> --
> You received this message because you are subscribed to the Google Groups 
> "DataMapper" group.
> To post to this group, send email to datamap...@googlegroups.com.
> To unsubscribe from this group, send email to 
> datamapper+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/datamapper?hl=en.
>
>
>
>

Instead of `after :save` you could try using a lambda or Proc with
default and doing something like

     property :derived1,String, :default => Proc.new { |r,l| "#{r.body}.db"}

If you expect body to change after new is called, you could put it in
a `before :save` call instead.

    before :save do
      self.derived1 = "#{r.body}.db"
    end

or


    before :save do
      self.derived1 = "#{r.body}.db" unless derived1
    end

if you don't want to clobber earlier values.

-- 
-Nick Howard
http://blog.baroquebobcat.com/
-- 
You received this message because you are subscribed to the Google Groups 
"DataMapper" group.
To post to this group, send email to datamap...@googlegroups.com.
To unsubscribe from this group, send email to 
datamapper+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/datamapper?hl=en.


Reply via email to