在单独的表单上设计用户的配置文件模型

时间:2014-08-02 12:14:08

标签: ruby-on-rails validation activerecord devise

我的设计用户链接到has_one :profile的个人资料模型我希望保留初始用户表单非常简单,使用标准用户名电子邮件和密码。我想在第一次登录时提示用户提供个人资料编辑表单,我希望他们被迫填写一些数据。

目前我的个人资料模型是:

class Profile < ActiveRecord::Base
  attr_accessible :time_zone, :telephone, :country, :opt_out, 
    :first_name, :last_name, :address, :city, :postcode, :birthdate, 
    :currency_id

  belongs_to :currency

  validates_presence_of :telephone, :country, :first_name, :last_name, 
    :address, :city, :postcode, :birthdate, :currency

  belongs_to :user
end

我的用户模型是:

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
    :recoverable, :rememberable, :trackable, :validatable, :confirmable

  before_create :initialize_user
  before_destroy :destroy_profile

  has_one :profile
  has_one :subscription

  attr_accessible :email, :password, :password_confirmation, :remember_me, 
    :username, :terms

  validates_acceptance_of :terms
  validates_presence_of :username

private
  def initialize_user
    generate_profile
    generate_free_subscription
  end

  def generate_free_subscription
    subscription = Subscription.new() do |s|
      s.expiration_date = nil
      s.plan = :free
      s.billing_name = username
      s.billing_street = "unknown"
      s.billing_zip = "unknown"
      s.billing_city = "unknown"
      s.billing_country = "unknown"
      s.billing_email = email
    end

    if subscription.save
      self.subscription = subscription
      self.roles = [:free]
    else
      msg = "Error generating free subscription for user, #{subscription.errors.to_yaml}"
      logger.error  msg
      raise msg
    end
  end

  def generate_profile
    p = Profile.new() do |p|
      p.daily_capital_exposure = 50
      p.risk_per_day = 60
      p.risk_per_trade = 30
      p.risk_per_week = 90
      p.user_id = self.id
      p.time_zone = "Rome"
    end

    if p.save
      self.profile = p
    else
      msg = "Error generating profile for user #{p.errors}"
      logger.error  msg
      raise msg
    end
  end

  def destroy_profile
    p = self.profile
    t = self.trades

    p.destroy
    t.destroy_all
  end
end

我的问题是,当我创建用户时,回调还会创建其配置文件,这会丢失一些数据,因此无法创建配置文件。

我不想插入配置文件临时数据只是为了使配置文件正确验证,因为我真的希望有一种很好的方法来强制用户插入这些信息。

我想我的错误是我在创建用户时不应该创建个人资料,但我不确定如何确保创建个人资料。

2 个答案:

答案 0 :(得分:2)

尝试使用类似的方法在开头创建默认配置文件:

class User < ActiveRecord::Base
  rolify
  searchkick autocomplete: [:fullname]
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  has_one :profile

  before_create :build_default_profile



  private
  def build_default_profile
    # build default profile instance. Will use default params.
    # The foreign key to the owning User model is set automatically
    build_profile
    true # Always return true in callbacks as the normal 'continue' state
    # Assumes that the default_profile can **always** be created.
    # or
    # Check the validation of the profile. If it is not valid, then
    # return false from the callback. Best to use a before_validation
    # if doing this. View code should check the errors of the child.
    # Or add the child's errors to the User model's error array of the :base
    # error item
  end
end

这将在您创建用户时创建个人资料。

此外,如果您想在注册过程中使用全名,我会这样做:

#application_controller
 before_action :configure_permitted_parameters, if: :devise_controller?

private
    def configure_permitted_parameters
        devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:fullname, :email, :password, :password_confirmation) }
        devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:avatar, :fullname, :email, :password, :password_confirmation, :current_password) }
      end

这样,您应该能够在注册期间获取名字,然后创建配置文件,然后在用户登录后,您可以将其重定向到配置文件创建页面,在该页面中可以要求用户填写其他用户的信息。

希望我能提供帮助。

答案 1 :(得分:1)

您可以在Profile验证中使用on:选项:

#app/models/profile.rb
Class Profile < ActiveRecord::Base
   validates_presence_of :telephone, :country, :first_name, :last_name, 
    :address, :city, :postcode, :birthdate, :currency, on: :update #-> means this will not fire on create
end

-

关于创建building的{​​{1}}您的个人资料模型,我们使用以下设置:

User

这会在创建父模型时为#app/models/user.rb Class User < ActiveRecord::Base before_create :build_profile end 模型创建一个配置文件