我有一个有多个计划的应用。对于"团队"计划,用户将输入团队名称和许可证计数。创建用户后,将保存新团队。我想我的数据库部分是正确的,但我对如何创建团队感到困惑。更具体地说,我的问题是: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>