【问题标题】:ruby on Rails make unique Profile for a Userruby on Rails 为用户创建独特的配置文件
【发布时间】:2016-04-20 18:11:00
【问题描述】:

我有两个模型,一个是用户,另一个是个人资料

class User < ActiveRecord::Base
   has_one :profile
   delegate :first_name, :last_name, :email, :phone, :location, to: :profile
end


class Profile < ActiveRecord::Base
  belongs_to :user
end

如何验证用户个人资料的唯一性,因为每次对于同一个用户,它在用户注销并再次通过omniauth 登录后创建许多个人资料

如下图

def self.from_omniauth(auth)
      where(auth.slice(:provider, :uid).permit!).first_or_initialize.tap do |user|
        user.provider = auth.provider
        user.uid = auth.uid
        user.name = auth.info.name
        user.oauth_token = auth.credentials.token
        user.refresh_token = auth.credentials.refresh_token


        user.build_profile(first_name: auth.info.first_name, last_name: auth.info.last_name, email: auth.info.email, location: auth.info.location, phone: auth.info.phone)
        user.save!
      end
    end

如何为 uniq 用户制作唯一的优先文件。

一种方法

 def self.from_omniauth(auth)
      where(auth.slice(:provider, :uid).permit!).first_or_initialize.tap do |user|
        user.provider = auth.provider
        user.uid = auth.uid
        user.name = auth.info.name
        user.oauth_token = auth.credentials.token
        user.refresh_token = auth.credentials.refresh_token
        user.auth_token = auth.credentials.token
        user.instance_url = auth.credentials.instance_url
        user.save!
        if Profile.exists?(email: auth.info.email)
          user.profile = Profile.where(email: auth.info.email).first
          user.save
        else    
          user.build_profile(first_name: auth.info.first_name, last_name: auth.info.last_name,\
         email: auth.info.email, location: auth.info.location, phone: auth.info.phone).save
        end   
      end
    end

但这不是一个好办法

我知道这是非常基本的,但想要一个最好的方法..

提前致谢

【问题讨论】:

  • has_one 应该会产生一个唯一的条目,通过覆盖以前的条目,您是否看到了其他内容?
  • 感谢 Brad 的回复,是的,每次登录后都会创建重复的配置文件我使用的是 rails 4.2.3
  • 我的意思是 User.first.profile 将显示一个配置文件,但如果我这样做 Profile.all 我有很多重复记录意味着每次登录它都会创建配置文件我如何检查防止此重复记录的最佳方法创作

标签: ruby-on-rails ruby ruby-on-rails-4


【解决方案1】:

您可以向用户模型添加验证。检查以下示例。

class User < ActiveRecord::Base
  has_one :profile
  delegate :first_name, :last_name, :email, :phone, :location, to: :profile

  validate :profile_exists

  private

  def profile_exists
    self.errors.add("profile", "already exists.") if self.profile.present?
  end
end

对您的代码进行一些编辑,检查以下内容。

def self.from_omniauth(auth)
  where(auth.slice(:provider, :uid).permit!).first_or_initialize.tap do |user|
    user.provider = auth.provider
    user.uid = auth.uid
    user.name = auth.info.name
    user.oauth_token = auth.credentials.token
    user.refresh_token = auth.credentials.refresh_token
    user.auth_token = auth.credentials.token
    user.instance_url = auth.credentials.instance_url
    user.save!
    if user.profile.present?
      user.profile.update(email: auth.info.email)
    else    
      profile = user.build_profile(first_name: auth.info.first_name, last_name: auth.info.last_name, email: auth.info.email, location: auth.info.location, phone: auth.info.phone)
      profile.save
    end   
  end
end

【讨论】:

  • 啊,我做到了,但在注销用户后删除并重置会话,但配置文件未删除,因此该用户无法再次登录
  • @MitaDas 请发布您的注销方法。
【解决方案2】:

您对business logicdata integrity 感到困惑。

--

您的模型 (db) 结构应该是每个user 应该有一个 profile。该用户是否登录、吃咖喱或洗衣服都没有关系;他还有一个个人资料:

#app/models/user.rb
class User < ActiveRecord::Base
   has_one :profile
   accepts_nested_attributes_for :profile

   before_create :build_profile
end

#app/models/profile.rb
class Profile < ActiveRecord::Base
   belongs_to :user
end 

user对象被创建时,上面创建了一个新的profile。您的现有代码已经具备此功能。

不同之处在于上面创建了数据结构,您可以在之后应用业务逻辑。

您对这些数据(业务逻辑)做什么是根据每个用户都有一个配置文件这一事实委派的:

def self.from_omniauth(auth)
      where(auth.slice(:provider, :uid).permit!).first_or_initialize.tap do |user|
        user.provider = auth.provider
        user.uid = auth.uid
        user.name = auth.info.name
        user.oauth_token = auth.credentials.token
        user.refresh_token = auth.credentials.refresh_token

        user.profile.first_name = auth.info.first_name
        user.profile.last_name  = auth.info.last_name 
        user.profile.email      = auth.info.email
        user.profile.location   = auth.info.location
        user.profile.phone      = auth.info.phone
        user.save!
      end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多