Reputation: 10207
In my Rails 4 application I have users
who can have many rates
.
class Rate < ActiveRecord::Base
belongs_to :user
validates :name, :presence => true
validates :amount, :presence => true
...
end
A rate has a name
, an amount
, and a boolean attribute default
.
How can I make sure that the user
cannot accidentally delete his last rate
, i.e. that at least one rate always remains associated with the user and that that rate's default attribute is set to true
if there is no other rate remaining?
Thanks for any ideas.
Upvotes: 1
Views: 179
Reputation: 11
You could move the validation to the User, and manage the Rates as nested attributes. something like
class User < ActiveRecord::Base
has_many :rates, dependent: :destroy
accepts_nested_attributes_for :rates, allow_destroy: true
validates_presence_of :rates
end
and rates need not worry
class Rate < ActiveRecord::Base
belongs_to :user
after_initialize :set_default, if: ->{ user.rates.count == 1 }
...
private
def set_default
self.default = true
end
end
Upvotes: 1
Reputation: 21
maybe something like...
class Rate < ActiveRecord::Base
belongs_to :user
validates :name, :presence => true
validates :amount, :presence => true
after_initialize :set_default, if: ->{ user.rates.count == 1 }
after_destroy :ensure_rate_exists
private
def set_default
self.default = true
end
def ensure_rate_exists
raise "Cannot remove.." if user.rates.count.zero?
end
end
Upvotes: 2
Reputation: 3371
You can do it using a specific method like this
class User
def delete_rate(rate)
if rates.count > 1
self.rates.delete(rate)
else
raise "User should have at least one rate"
end
end
end
Or you can add a validation like this :
class User
validates :rates, length: { minimum: 1 }
end
but this last solution can introduce issues on User creation.
Upvotes: 2