-
-
Save badosu/cd7a018f7f7d45836903 to your computer and use it in GitHub Desktop.
require 'sequel' | |
require 'sqlite3' | |
DB = Sequel.connect 'sqlite:/' | |
DB.create_table?(:people) do | |
primary_key :id | |
String :name | |
foreign_key :address_id, :addresses | |
end | |
DB.create_table?(:addresses) do | |
primary_key :id | |
String :street | |
end | |
class Person < Sequel::Model | |
many_to_one :address | |
def after_destroy | |
address.destroy if Person.where(address_id: address_id).empty? | |
end | |
end | |
class Address < Sequel::Model | |
one_to_many :people | |
end | |
address = Address.create(street: "Elm Street") | |
adam = Person.create(name: "Adam", address: address) | |
john = Person.create(name: "John", address: address) | |
puts "Before destroying people: #{Address.count}" | |
adam.destroy | |
puts "After destroying adam: #{Address.count}" | |
john.destroy | |
puts "After destroying john: #{Address.count}" | |
# Should output: | |
# | |
# Before destroying people: 1 | |
# After destroying adam: 1 | |
# After destroying john: 0 |
Thanks for the comment! :)
So, I applied your change but it did not work as intended:
Before destroying people: 1
After destroying adam: 1
After destroying john: 1
I guess it's because I do not want specifically to remove an address every time a person is deleted, I want to remove an address always when the last person that belonged to that address is deleted.
Oh I see. Addresses is not something I'd share between users, but I guess you were just illustrating the point, right? Even though, I'd rather use what I call a use case to encapsulate the person[+address] deletion process, at least that's how I see it now. Models are just for hitting the database, I strive to use regular ruby classes for implementing application-specific logic.
I have some good examples I'd like to bounce off you (and anyone else you'd like to listen). Please remind me to do so the next time we see each other :)
badosu was kindly helping me out, cristianrasch. As it happens, what he proposed works the way I had hoped.
As a parish minister, it works well for me to have addresses in a different table from people. The reason for that is that the addresses are generally geographically grouped into pastoral+administrative districts. It is often useful to know how many addresses are in a district as well as how many people are in a household. It is more helpful for my purpose to have a list of unique addresses for a district than to list multi-occupant addresses for each occupant.
It's a real simple change, take this line out:
foreign_key :address_id, :addresses
and replace it with this one instead:
foreign_key :address_id, :addresses, null: false, on_delete: :cascade
Now every time you delete a parent object (Person), their addresses are mass-deleted automatically for you :) - it also has the added benefits of referential integrity