Posted almost 11 years ago. Visible to the public.

ActiveRecord: Overwriting a setter causes trouble with attributes depending on each other

Undeterministically I got a nil error on saving the object caused by the random order of hash elements of the params hash.

class Feedback belongs_to :user def role=(value) @role = value = find_email_by_name( end end

This piece of code works well until the object params hash contains a second element when it is updated like this:


Now it is no longer ensured that user was set before name was set. If the name setter is called before the user setter you will receive an error (no method #email for nil).

Workaround 1: Don't use clever setters

Don't write clever setters. Set inferred attributes before validation instead:

before_validation :set_email_from_name

The callback before_validation happens after all setters happened.

Workaround 2: Hack the attributes setter

This solution should only be used if you work on a large application where a lot of code depends on the indeterministic behavior above, and it would be too much work to refactor the whole app for a small change.

Using the attached trait you can say

does 'priority_attributes', %w[user_id other_attribute]

This makes sure that user_id and other_attribute are set before any other attributes.

Your development team has a full backlog of feature requests, chores and refactoring coupled with deadlines? We are familiar with that. With our "DevOps as a Service" offering, we support developer teams with infrastructure and operations expertise.

Owner of this card:

Martin Straub
Last edit:
over 10 years ago
problem, error
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Martin Straub to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more