Save! neither saves nor raises error

I don’t like this. This makes me grumpy, and I’ve even already had my
morning coffee.

obs[0] is a PremiseObservation, save! completed without error, yet
nothing was written to the db. This is a serious ass-biter:

irb(main):057:0> PremiseObservation.count
=> 0
irb(main):058:0> obs =
PremiseObservation.get_premise_observations(premise) ; obs.size
=> 320
irb(main):059:0> obs[0].is_a?(PremiseObservation)
=> true
irb(main):060:0> obs[0].save!
=> true
irb(main):061:0> PremiseObservation.count
=> 0

FTW?

Full disclosure: PremiseObservation.get_premise_observations()
constructs its data through a (massive) find_by_sql() query, but whose
SELECT takes pains to match the PremiseObservation schema. I could
understand if obs[0] was tagged readonly as a result, but it’s not:

irb(main):062:0> obs[0].readonly?
=> false

How can save! complete without error and yet not save anything? Either
I’ve overlooked some key piece of documentation or else this is a bug.
Which is it?

  • ff

ps:I’m sure I can work around this by creating a virgin
PremiseObservation and copying each field over into it. That’s a PITA,
but manageable.

pps: bash$ rake about
(in /Users/ff/Developer/dev)
About your application’s environment
Ruby version 1.9.2 (x86_64-darwin10.4.0)
RubyGems version 1.3.7
Rack version 1.2
Rails version 3.0.0.rc
Active Record version 3.0.0.rc
Action Pack version 3.0.0.rc
Active Resource version 3.0.0.rc
Action Mailer version 3.0.0.rc
Active Support version 3.0.0.rc
Application root /Users/ff/Developer/bd
Environment development

On Aug 17, 8:42 pm, Fearless F. [email protected] wrote:

How can save! complete without error and yet not save anything? Either
I’ve overlooked some key piece of documentation or else this is a bug.
Which is it?

You’ve got it out of find_by_sql so rails thinks its an existing row.
Furthermore rails doesn’t think the object has changed since you
retrieved it from the database, so it shortcircuits the save (since
from its point of view there is nothing to save)

Fred

Frederick C. wrote:

You’ve got it out of find_by_sql so rails thinks its an existing row.
Furthermore rails doesn’t think the object has changed since you
retrieved it from the database, so it shortcircuits the save (since
from its point of view there is nothing to save)

Fred

Fred:

Your explanation makes sense. If this is not a bug in ActiveRecord,
then there IS a bug in the documentation – it has to be one or the
other. This is new territory for me: is there a writeup on how to
properly report a documentation bug?

A second (and lesser) question: is there a way to force a save? That
would save me creating and copying a new one.

Thanks.

  • ff

On Aug 17, 9:31 pm, Fearless F. [email protected] wrote:

Your explanation makes sense. If this is not a bug in ActiveRecord,
then there IS a bug in the documentation – it has to be one or the
other. This is new territory for me: is there a writeup on how to
properly report a documentation bug?

I’m not sure that’s true - you’re doing something that is really
rather strange.
I’d get in touch with the docrails folks - ask around in #rails-
contrib

A second (and lesser) question: is there a way to force a save? That
would save me creating and copying a new one.

in this particular case you don’t just need to mark the record as
dirty, you need to mark the record as being a new record. As far as I
know the only way to do that is to set the new_record instance
variable. Personally I’d take the need to muddle with AR internals as
a hint not to do this.

Fred

Quoting Fearless F. [email protected]:

=> 320
irb(main):059:0> obs[0].is_a?(PremiseObservation)
=> true
irb(main):060:0> obs[0].save!
=> true
irb(main):061:0> PremiseObservation.count
=> 0

Try ‘obs[0].touch’. Quoting the documentation at
http://rails.rubyonrails.org/:

touch(attribute = nil)

Saves the record with the updated_at/on attributes set to the current
time. If the save fails because of validation errors, an
ActiveRecord::RecordInvalid exception is raised. If an attribute name is
passed, that attribute is used for the touch instead of the
updated_at/on attributes.

Examples:

product.touch # updates updated_at
product.touch(:designed_at) # updates the designed_at attribute

HTH,
Jeffrey

Jeffrey L. Taylor wrote:

Try ‘obs[0].touch’. Quoting the documentation at
http://rails.rubyonrails.org/:

Jeffrey: That’s a great idea, but didn’t work:

irb(main):034:0> PremiseObservation.count
=> 0
irb(main):035:0> obs.touch
=> false
irb(main):036:0> obs.save!
=> true
irb(main):037:0> PremiseObservation.count
=> 0

I’ve filed a ticket on this, either as an AR or a documentation bug.
We’ll see what the core team has to say about it.