Forum: Ruby on Rails One-way change

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Chris S. (Guest)
on 2006-03-06 05:01
I'm developing an app, and I want to make a single boolean field OK to
change from 0 to 1, but not allow 1 to 0.

Seems like the model's validate method would be the right place for
this, but I'm not sure how to implement it.

Any suggestions (actual or pointers to) are greatly appreciated.
Gregory S. (Guest)
on 2006-03-06 16:34
(Received via mailing list)
On Mon, Mar 06, 2006 at 04:01:46AM +0100, Chris S. wrote:
} I'm developing an app, and I want to make a single boolean field OK to
} change from 0 to 1, but not allow 1 to 0.
}
} Seems like the model's validate method would be the right place for
} this, but I'm not sure how to implement it.
}
} Any suggestions (actual or pointers to) are greatly appreciated.

This is the sort of thing I'd do in a database trigger. When you attempt
to
save, the trigger will get activated and throw a hissy if necessary,
which
will cause ActiveRecord to tell you that the save failed.

--Greg
Chris S. (Guest)
on 2006-03-06 17:03
> This is the sort of thing I'd do in a database trigger. When you attempt
> to save, the trigger will get activated and throw a hissy if necessary,
> which will cause ActiveRecord to tell you that the save failed.
>
> --Greg

That sounds like it would work... and like something I don't want to do.
There has to be a way to do it in Rails. I just thought it might be an
easy thing.

I suppose I could put it in the view that if the flag is set, don't put
up a field for a new entry. That doesn't seem so awful now that I think
about it, except that the rule should go in the model.

def validate_on_update
  oldobj = find(obj.id);
  if (oldobj.field == 1) and (field == 0)
    errors.add("field", "cannot be cleared once set")
  end
end

I know I can get the new values, but is the old object around? I could
go get the record as it's already stored, but it seems it might already
exist somewhere.
Gregory S. (Guest)
on 2006-03-06 17:38
(Received via mailing list)
On Mon, Mar 06, 2006 at 04:03:06PM +0100, Chris S. wrote:
} > This is the sort of thing I'd do in a database trigger. When you
attempt
} > to save, the trigger will get activated and throw a hissy if
necessary,
} > which will cause ActiveRecord to tell you that the save failed.
} >
} > --Greg
}
} That sounds like it would work... and like something I don't want to
do.
} There has to be a way to do it in Rails. I just thought it might be an
} easy thing.
}
} I suppose I could put it in the view that if the flag is set, don't
put
} up a field for a new entry. That doesn't seem so awful now that I
think
} about it, except that the rule should go in the model.
}
} def validate_on_update
}   oldobj = find(obj.id);
}   if (oldobj.field == 1) and (field == 0)
}     errors.add("field", "cannot be cleared once set")
}   end
} end
}
} I know I can get the new values, but is the old object around? I could
} go get the record as it's already stored, but it seems it might
already
} exist somewhere.

Well, your other option is to override the field= method in the model.
For
example, suppose your field is named foo:

def foo=(value)
  fail "Goodbye, cruel world!" if foo == 1 && value == 0
  super(value)
end

Of course, this assumes that the only way the value of foo is modified
is
through the mutator method, and I believe that is the case.

--Greg
Chris S. (Guest)
on 2006-03-06 17:44
> Well, your other option is to override the field= method in the model.
> For example, suppose your field is named foo:
>
> def foo=(value)
>   fail "Goodbye, cruel world!" if foo == 1 && value == 0
>   super(value)
> end
>
> Of course, this assumes that the only way the value of foo is modified
> is through the mutator method, and I believe that is the case.

Brilliant. This should do the job exactly. Thanks!
This topic is locked and can not be replied to.