Rails上的ruby为用户创建唯一的配置文件

时间:2016-01-15 07:27:37

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

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

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用户制作独特的priofile。

我做的一种方式

 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

但这不是一个好方法

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

提前致谢

2 个答案:

答案 0 :(得分:2)

您在business logicdata integrity之间感到困惑。

-

您的模型(db)结构应该是每个chmod -R 777 YOURPROJECT_FOLDER应该一个 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 对象时,上面会创建一个新的profile。您已经在现有代码中使用了此功能。

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

您使用该数据(业务逻辑)执行的操作是根据每个用户都有一个配置文件的事实委派的:

user

答案 1 :(得分:0)

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

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