【问题标题】:Rails Copying attributes from User object to new objectRails将属性从用户对象复制到新对象
【发布时间】:2017-03-22 20:54:13
【问题描述】:

在用户模型中,我有一个存档!销毁用户时调用的方法。此操作在单独的表中创建一个新的 ArchivedUser。

ArchivedUser 已成功创建,但我手动设置每个值的方式很脏;如果将新列添加到 User 表中,也必须在此处添加。

我尝试了selectslice的属性,但是得到了undefined local variable or methoduser'``

ArchivedUser.create(user.attributes.select{ |key, _| ArchivedUser.attribute_names.include? key })

ArchivedUser.create(user.attributes.slice(ArchivedUser.attribute_names))

在使用 self 创建 ArchivedUser 时,如何遍历 User 表中的每个属性?

def archive!
    if ArchivedUser.create(
        user_id: self.id,
        company_id: self.company_id,
        first_name: self.first_name,
        last_name: self.last_name,
        email: self.email,
        encrypted_password: self.encrypted_password,
        password_salt: self.password_salt,
        session_token: self.session_token,
        perishable_token: self.perishable_token,
        role: self.role,
        score: self.score,
        created_at: self.created_at,
        updated_at: self.updated_at,
        api_key: self.api_key,
        device_id: self.device_id,
        time_zone: self.time_zone,
        device_type: self.device_type,
        verified_at: self.verified_at,
        verification_key: self.verification_key,
        uninstalled: self.uninstalled,
        device_details: self.device_details,
        is_archived: self.is_archived,
        registered_at: self.registered_at,
        logged_in_at: self.logged_in_at,
        state: self.state,
        creation_state: self.creation_state,
        language_id: self.language_id,
        offer_count: self.offer_count,
        expired_device_id: self.expired_device_id,
        unique_id: self.unique_id,
        best_language_code: self.best_language_code,
        offer_id: self.offer_id,
        vetted_state: self.vetted_state,
        photo_path: self.photo_path
      )

      self.is_archived = true

      self.email = "#{self.email}.archived#{Time.now.to_i}"
      self.encrypted_password = nil
      self.password_salt      = nil
      self.session_token      = nil
      self.perishable_token   = nil
      self.device_id          = nil
      self.verification_key   = nil
      self.save!

      self.update_column(:api_key, nil)
      UserGroup.delete_all(:user_id => self.id)
    else
      # handle the ArchivedUser not being created properly
    end
  end

感谢观看:)

更新:

我们能够找出ArchivedUser.create(self.attributes.slice!(ArchivedUser.attribute_names) 不起作用的原因。第一个原因是create 方法需要“砰”地写对象。第二个原因是 ArchivedUser 有一个 user_id 字段,用户在创建之前不会收到该字段。我们必须手动设置 user_id: merge(user_id: self.id)

最终输出看起来像 ArchivedUser.create!(self.attributes.slice!(ArchivedUser.attribute_names).merge(user_id: self.id))

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    您在第一次实施时走在了正确的轨道上。你只需要使用 self 而不是 user。

    ArchivedUser.create(self.attributes.slice(ArchivedUser.attribute_names))
    

    【讨论】:

    • 感谢 Ehren...虽然这有效并显示了 flash 消息,但 ArchivedUser 实际上并没有在 ArchivedUser 表中创建,这很奇怪。
    • @VegaStudios 好的,这可能是因为验证。尝试使用 create! 而不是 create 来获取验证消息的异常。
    • 哼,抛出了验证失败的错误:用户不能为空。我将不得不做一些挖掘......
    • 是的!啊,您的 ArchivedUser 可能有一个普通用户没有的用户字段。您只需要另一条线在切片线之后设置它。只需archived_user = ArchivedUser.new(<snip>); archived_user.user = self; archived_user.save!
    • 啊!我正在累积学习:D 感谢您引导我完成。
    【解决方案2】:

    如果您只想拥有正在存档的用户的副本,我认为一种优雅的方式是这样做

    archived_user = user_to_be_archived.dup

    或者您可以查看 amoeba gem,如果您愿意,这将完成所有繁重的工作,包括关联。 https://github.com/amoeba-rb/amoeba

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 2016-12-21
      • 2017-05-08
      • 1970-01-01
      相关资源
      最近更新 更多