Я пытаюсь выяснить, есть ли способ сделать это в Rails более эффективно.
Существует довольно долгая настройка для этого вопроса, поэтому, пожалуйста, потерпите меня.Допустим, у меня есть модели Клиент, Телефон, Адрес
Вот примеры миграций, чтобы дать вам представление:
class CreatePhones < ActiveRecord::Migration
def self.up
create_table :phones do |t|
t.integer :country_prefix, :limit => 3
t.integer :area_prefix, :limit => 5
t.integer :number, :limit => 7
t.integer :category_id
t.references :phonable, :polymorphic => true
t.timestamps
end
end
end
class CreateAddress < ActiveRecord::Migration
def self.up
create_table :addresses do |t|
t.string :address_line_1
t.string :address_line_2
t.string :address_line_3
t.string :city
t.string :state
t.string :zip
t.string :country
t.string :attn
t.integer :category_id
t.references :addressable, :polymorphic => true
t.timestamps
end
end
end
class CreateCategories < ActiveRecord::Migration
def self.up
create_table :categories do |t|
t.string :name
t.string :code
t.integer :category_id # Every subcategory has a category: i.e. phone has work, fax,mobile
t.timestamps
end
end
end
class CreateCustomers < ActiveRecord::Migration
def self.up
create_table :customers do |t|
t.string :code , :limit => 20 , :null => false
t.string :name , :null => false
t.string :billing_name
t.integer :preferred_shipping_method_id
end
end
Вот модели и отношения:
class Customer < ActiveRecord::Base
belongs_to :preferred_shipping_method , :class_name => "Category", :foreign_key => :preferred_shipping_method_id
has_many :addresses, :as => :addressable, :include => :category, :dependent => :destroy
has_many :phones, :as => :phonable, :include => :category, :dependent => :destroy
end
class Category < ActiveRecord::Base
has_many :addresses
has_many :phones
has_many :customer_by_shipping_methods, :class_name => "Customer", :foreign_key => :preferred_shipping_method_id
has_many :subcategories, :class_name => "Category", :foreign_key => :category_id
belongs_to :category, :class_name => "Category"
end
class Address < ActiveRecord::Base
belongs_to :category
belongs_to :addressable, :polymorphic => true
end
class Phone < ActiveRecord::Base
belongs_to :category
belongs_to :phonable, :polymorphic => true
end
Вот вопрос.
Допустим, у меня есть запись клиента с кучей телефонов (мобильный, рабочий) и адреса (биллинг, доставка).
old = Customer.where(:code => "ABC").first
Затем я создаюили импортирование (из устаревшей БД) другого объекта клиента
new = Customer.new
new.code = "ABC"
new.phones.build(:number => "12345567")
и т. д.
Затем я хочу сравнить информацию о старом клиенте с информацией о новом клиенте и на основе этого обновления старой информации о клиенте.
Примерно так:
if old.eql?(new) # this should compare not only, name & code and such but also polymorphic associations
old.update_with(new) # this should update old info attributes with new if there is new info, or if update / add to one of the associations
old.save #
else
new.save
end
Таким образом, вопрос в том, существует ли КОНВЕНЦИОННЫЙ способ в Rails 3 делать то, что я описываю в комментариях?
Прямо сейчас я переопределяюхэш & eql?методы, которые хорошо для сравнения.Но обновление каждого атрибута и каждого связанного объекта и его атрибутов становится своего рода вовлечением.Мне было интересно, если есть более простой способ сделать это, то мой путь:
class Customer < ActiveRecord::Base
def hash
%{#{ name }#{ code }}.hash # There is a lot more here of course
end
def eql?(other)
hash == other.hash
end
def update_with(other)
name = other.name
code = other.code
etc ....
end
end