将 iphone 联系人与 Rails 同步
我已经构建了 Rails 模型架构来匹配 iPhone 联系人s,其中包括多值电子邮件关联等。我有一个控制器操作,用于导入整个联系人数组(可能有 1,000 多个对象,每个对象可能包含多个电子邮件对象)。我需要它才能相当有效地运行,所以我正在寻找 activerecord-import 进行批量导入。但是,我需要验证每个联系人范围内电子邮件的唯一性,这样我就不会在每次导入批次时都不断添加重复项。我应该手动构建自己的 update_attributes
版本,还是有您可能推荐的现有解决方案来验证/更新大量这样的记录?
联系人模型
class Contact > ActiveRecord::Base has_many :addresses has_many :emails has_many :websites accepts_nested_attributes_for :addresses, :emails, :websites attr_accessible :prefix, :first_name, :middle_name, :last_name, :suffix, :nickname, :organization, :job_title, :department, :birthday, :addresses_attributes, :emails_attributes, :websites_attributes end
电子邮件模型
class Email > ActiveRecord::Base belongs_to :contact # validates_uniqueness_of :account, :scope => :contact_id # prevents duplicate, but also skips sibling values # validates :contact_id, :presence => true, :on => :create # causes 422 error validates :account, :presence => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create attr_accessible :contact_id, :email_id, :account, :label end
I have built my Rails model schema to match the iphone contacts, which includes multi-value email associations, etc. I have a controller action that imports an entire contacts array (likely 1,000+ objects, each potentially containing multiple email objects). I need this to run fairly efficiently, so I was looking at activerecord-import for batch importing. However, I need to validate the uniqueness of the email within the scope of each contact so that I don't keep adding duplicates every time the batch is imported. Should I build my own version of update_attributes
by hand, or is there an existing solution that you might recommend for validating/updating lots of records like this?
Contact Model
class Contact > ActiveRecord::Base has_many :addresses has_many :emails has_many :websites accepts_nested_attributes_for :addresses, :emails, :websites attr_accessible :prefix, :first_name, :middle_name, :last_name, :suffix, :nickname, :organization, :job_title, :department, :birthday, :addresses_attributes, :emails_attributes, :websites_attributes end
Email Model
class Email > ActiveRecord::Base belongs_to :contact # validates_uniqueness_of :account, :scope => :contact_id # prevents duplicate, but also skips sibling values # validates :contact_id, :presence => true, :on => :create # causes 422 error validates :account, :presence => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create attr_accessible :contact_id, :email_id, :account, :label end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
activerecord-import 中没有内置支持执行此操作。
但是,如果您在导入时知道 contact_id 和电子邮件地址,则可以对 contact_id 和电子邮件地址使用唯一索引。在MySQL中,您可以使用ON DUPLICATE KEY UPDATE 支持(activerecord-import 确实支持 this) 不导入重复项,而是更新现有记录。对于 MySQL,您还可以使用 INSERT IGNORE(activerecord-import 支持此功能),这将在导入导致索引违规的记录时忽略任何错误(这是避免重复的另一种方法)。
如果您使用其他 RDMS(例如 PostgreSQL 或 SQLite),那么您将需要查看他们的文档以了解如何忽略违反键约束(例如 INSERT IGNORE)。我不相信任何类似于开箱即用的 ON DUPLICATE KEY UPDATE 的支持。
如果您在要导入时不知道 contact_id 和电子邮件地址,那么您必须在代码中做一些前期工作,以获得有关是否要复制或创建的足够信息。
希望这有帮助。
There is no built-in support in activerecord-import for doing this.
However, if you know both the contact_id and the email address at the time of import you can use a unique index on the contact_id and the email address. In MySQL, you can use the ON DUPLICATE KEY UPDATE support (activerecord-import does support this) to not import a duplicate, but to rather update the existing record. With MySQL you can also use INSERT IGNORE (activerecord-import supports this to) which will ignore any errors when importing records that cause index violations (this is another way to avoid duplicates).
If you are using another RDMS like PostgreSQL or SQLite then you will want to look at their docs to see how you can ignore violating key constraints (like INSERT IGNORE). I do not believe either support anything similar to ON DUPLICATE KEY UPDATE out of the box.
If you don't know both the contact_id and the email address at the time you want to import then you'll have to do a little upfront work in your code to have enough information about whether you'd be duplicating or creating.
Hope this helps.