Rails和devise - 在用户注册时分配组

时间:2014-08-19 18:55:35

标签: ruby-on-rails ruby devise

我有一个有多个计划的应用。对于"团队"计划,用户将输入团队名称和许可证计数。创建用户后,将保存新团队。我想我的数据库部分是正确的,但我对如何创建团队感到困惑。更具体地说,我的问题是:1)如何将团队字段添加到视图中?我是否在用户表单中使用form_for并嵌套? 2)如何在控制器中处理团队创建?谢谢你的帮助。

迁移:

class CreateTeams < ActiveRecord::Migration

  def change
    create_table :teams do |t|
      t.string :team_name
      t.integer :license_count
      t.timestamps
    end

    add_column :users, :team_id, :integer, :null => true
    add_column :users, :team_admin, :boolean

  end
end

控制器:

class RegistrationsController < Devise::RegistrationsController

  def new
    return if plan_missing   
    build_resource({})
    self.resource.plan = params[:plan]
    respond_with self.resource
  end

  protected

  #after user has signed up
  def after_inactive_sign_up_path_for(resource)
    new_user_session_path
  end

  #after user has updated their profile, keep them on the same page
  def after_update_path_for(resource)
    edit_user_registration_path
  end

  private

  def plan_missing
    if params[:plan].nil?
      redirect_to plans_path
      true
    else
      false
    end
  end

  def log
    logger.debug @user.to_yaml
    logger.debug params.to_yaml
  end

end

模型:

class User < ActiveRecord::Base
  include KeyCreator

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, :trackable, :validatable

  belongs_to :teams
  has_many :document_users
  has_many :documents, :through => :document_users
  has_many :user_billing_events, dependent: :destroy

  before_create :before_create
  before_destroy :before_destroy
  after_destroy :after_destroy

  #scopes for activeadmin
  scope :new_users, -> { where("created_at >= ? and created_at <= ?",  Date.today.beginning_of_day.utc, Date.today.end_of_day.utc) }
  scope :admin, -> { where(:admin => true) }

  validates_inclusion_of :plan, in: %w( basic pro ), message: "Plan is not valid"

  attr_accessor :stripe_token, :coupon, :to_skip

  def is_admin?
    self.admin
  end

  def paid_plan
    ["pro", "team"].include? self.plan
  end

  def self.save_event(customer_id, event_type)
    user = User.find_by(customer_id: customer_id) 
    UserBillingEvent.create!(user: user, event_type: event_type)
  end

  def update_card(user)

    c = Stripe::Customer.retrieve(customer_id)
    c.card = user.stripe_token
    c.coupon = user.coupon unless user.coupon.blank?
    c.save

    self.customer_id = c.id
    self.last_4_digits = c.cards.data.first["last4"]
    self.stripe_token = nil  
    self.save!
    true

    rescue Stripe::StripeError => e
      logger.error "Stripe Error: " + e.message
      errors.add :base, "#{e.message}."
      self.stripe_token = nil
      false

  end

  def update_plan(user)

    self.stripe_token = user.stripe_token
    self.coupon = user.coupon

    if self.paid_plan && !user.paid_plan
      cancel_stripe
    end

    if !self.paid_plan && user.paid_plan
      setup_stripe
    end

    self.plan = user.plan
    self.save!
    true

  end

  def before_create
    self.api_key = create_key
    self.admin = false
    setup_stripe if self.paid_plan
  end

  def before_destroy
    cancel_stripe if self.paid_plan
  end

  def after_destroy
    self.documents.where(:document_users => {:role => "owner"}).destroy_all
    self.document_users.destroy_all
  end

  private

  def setup_stripe

    return if to_skip && to_skip.include?("stripe")

    logger.debug '-- setting up stripe... --'

    raise "Stripe token not present. Can't create account." if !stripe_token.present?

    if coupon.blank?
      customer = Stripe::Customer.create(:email => self.email, :description => self.name, :card => self.stripe_token, :plan => self.plan)
    else
      customer = Stripe::Customer.create(:email => self.email, :description => self.name, :card => self.stripe_token, :plan => self.plan, :coupon => self.coupon)
    end

    self.last_4_digits = customer.cards.data.first["last4"]
    self.customer_id = customer.id
    self.stripe_token = nil  

    customer

    rescue Stripe::StripeError => e
      logger.error "Stripe Error: " + e.message
      errors.add :base, "#{e.message}."
      self.stripe_token = nil
      nil #return nil

  end

  def cancel_stripe

    return if to_skip && to_skip.include?("stripe")

    logger.debug '-- cancelling stripe... --'

    customer = Stripe::Customer.retrieve(customer_id)
    return false if customer.nil?
    subscription = customer.subscriptions.data[0]
    customer.cancel_subscription if subscription.status == 'active'

    self.last_4_digits = nil
    self.customer_id = nil
    self.stripe_token = nil   

    true

    rescue Stripe::StripeError => e
      logger.error "Stripe Error: " + e.message
      errors.add :base, "#{e.message}."
      self.stripe_token = nil
      false

  end

  def trace
    logger.debug '-- tracing self in user.rb'
    logger.debug self.to_yaml
    logger.debug '--------------------------'
  end

end

class Team < ActiveRecord::Base
    has_many :users
end

注册视图:

<% content_for :head do %>
  <%= tag :meta, :name => "stripe-key", :content => ENV["STRIPE_PUBLIC_KEY"] %>
  <%= javascript_include_tag "https://js.stripe.com/v2/" %>
  <%= javascript_include_tag "stripe/application", "data-turbolinks-track" => true %>
<% end %>

<div class="container">

  <h2>Sign up for <%= @user.plan.titleize %></h2>

  <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), 
       :html => {:role => "form", class: @user.paid_plan ? "card-form" : ""} ) do |f| %>

    <%= devise_error_messages! %>

    <%= f.hidden_field :plan, :value => @user.plan %>

    <% if @user.plan == "team" %>
      <h3 class="vpad-top5">Team Administrator - User Account</h3>
    <% end %>

    <div class="form-group">
      <label for="name">Display Name</label>
      <%= f.text_field :name, :autofocus => true, :class =>"form-control" %>
    </div>

    <div class="form-group">
      <label for="email">Email</label>
      <%= f.email_field :email, :class =>"form-control" %>
    </div>

    <div class="form-group">
      <label for="password">Password</label>
      <%= f.password_field :password, :class =>"form-control"  %>
    </div>   

    <div class="form-group">
      <label for="password_confirmation">Password confirmation</label>
      <%= f.password_field :password_confirmation, :class =>"form-control"  %>
    </div>     

    <% if @user.plan == "team" %>

      <h3 class="vpad-top5">Team Information</h3>

      <!-- I need to add fields here! -->

    <% end %>

    <% if @user.paid_plan %>

      <h3 class="vpad-top5">Payment Information</h3>

      <%= render :partial => "shared/payment_fields", :locals => {:f => f} %>

    <% end %>

    <%= f.submit "Sign up",:class=>'btn btn-primary' %>

  <% end %>

  <%= render "devise/shared/links" %>

</div>

1 个答案:

答案 0 :(得分:1)

使用Rolify gem管理用户角色。

https://github.com/RolifyCommunity/rolify

您可以在用户注册时设置默认角色。