RailsApps / rails-stripe-membership-saas

An example Rails 4.2 app with Stripe and the Payola gem for a membership or subscription site.
http://railsapps.github.io/rails-stripe-membership-saas
1.14k stars 232 forks source link

Unpermitted Parameter for Subscription Plan #169

Closed RailsCod3rFuture closed 7 years ago

RailsCod3rFuture commented 7 years ago

I'm unable to get beyond this point. Devise is giving me issues with including the Subscription Model in the db transaction. When I add the :subscription_plan itself, I get a mismatch type error, expected 4 got a string.

class User::ParameterSanitizer < Devise::ParameterSanitizer
    def initialize(*)
      super
      permit(:sign_up, keys: [:username, :email, :first_name, :last_name, :country, :state, :city_or_town, :zip_code, :how_did_you_learn_about_us, :subscription_plan_id])
    end
  end
class User::RegistrationsController < Devise::RegistrationsController
  include Payola::StatusBehavior
  before_action :cancel_subscription, only: [:destroy]

  def new
    build_resource({})
    unless params[:subscription_plan].nil?
      @plan = SubscriptionPlan.find_by!(stripe_id: params[:subscription_plan])
      resource.subscription_plan = @plan
    end

    yield resource if block_given?
    respond_with self.resource
  end

  def create
    build_resource(sign_up_params)
    plan = SubscriptionPlan.find_by!(id: params[:user][:subscription_plan_id].to_i)
    resource.role = User.roles[plan.stripe_id] unless resource.nil?
    resource.save
    yield resource if block_given?
    if resource.persisted?
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_flashing_format?
        sign_up(resource_name, resource)
        subscribe
      else
        set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
        expire_data_after_sign_in!
        subscribe
      end
    else
      clean_up_passwords resource
      render json:
                 {error: resource.errors.full_messages.to_sentence},
             status: 400
    end
  end
 def user_change_plan
    plan = SubscriptionPlan.find_by!(id: params[:user][:subscription_plan_id].to_i)
    unless plan == current_user.plan
      role = User.roles[plan.stripe_id]
      if current_user.update_attributes!(subscription_plan: plan, role: role)
        subscription = Payola::Subscription.find_by!(owner_id: current_user.id)
        Payola::ChangeSubscriptionPlan.call(subscription, plan)
        redirect_to edit_user_registration_path, :notice => "Subscription plan changed Successfully"
      else
        flash[:alert] = 'Unable to change plan.'
        build_resource
        render :'users/registrations/edit'
      end
    end
  end

  protected
  def after_sign_in_path_for(resource)
    case current_user.role
      when 'silver'

      when 'gold'

      else
        root_path
    end
  end

  def after_update_path_for(resource)

  end

  private
  def subscribe
    return if resource.nil?
    params[:subscription_plan] = current_user.subscription_plan
    subscription = Payola::CreateSubscription.call(params, current_user)
    current_user.save
    render_payola_status(subscription)
  end

  def cancel_subscription
    subscription = Payola::Subscription.find_by!(owner_id: current_user.id, state: 'active')
    Payola::CancelSubscription.call(subscription)
  end
end

class User < ApplicationRecord
  enum role: [:user, :silver, :gold]
  after_initialize :set_default_role, :if => :new_record?
  after_initialize :set_default_plan, :if => :new_record?

  # Include default devise modules.
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable
  include DeviseTokenAuth::Concerns::User
  after_create :build_user_profile
  extend FriendlyId

  geocoded_by :last_sign_in_ip, :latitude => :lat, :longitude => :lon
  geocoded_by :user_address, :latitude => :lat, :longitude => :lon

  after_validation :geocode

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  friendly_id :username, use: :slugged
  belongs_to :subscription_plan

  # Validations
  validates_associated :subscription_plan
  validates :email, presence: true, uniqueness: true, email: {strict_mode: true}
  validates :username, presence: true, length: {maximum: 15, minimum: 2},
            format: {with: /\A[a-zA-Z0-9]+\Z/}, uniqueness: true
  validates :first_name, presence: true, uniqueness: false, length: {maximum: 50}, format: {with: /\A[a-zA-Z]+(?: [a-zA-Z]+)?\z/}
  validates :last_name, presence: true, uniqueness: false, length: {maximum: 50}, format: {with: /\A[a-zA-Z]+(?: [a-zA-Z]+)?\z/}
  validates :country, presence: true
  validates :state, presence: true
  validates :street, presence: true
  validates :city_or_town, presence: true, length: {maximum: 60, minimum: 2}
  validates :zip_code, presence: true, length: {maximum: 50}, format: {with: /\A[a-z0-9\s]+\Z/i}
  validates :password, password_strength: {use_dictionary: true}

  def user_address
    [street, state, city_or_town, zip_code, country].compact.join(', ')
  end

  def set_default_role
    self.role ||= :user
  end

  def set_default_plan
    self.subscription_plan ||= SubscriptionPlan.last
  end

  def sign_up_for_mailing_list
    UserMailingListSignupJob.perform_later(self)
  end

  def subscribe
    mailchimp = Gibbon::Request.new(api_key: Rails.application.secrets.mailchimp_api_key)
    list_id = Rails.application.secrets.mailchimp_list_id
    result = mailchimp.lists(list_id).members.create(
        body: {
            email: self.email,
            status: 'subscribed'
        })
    Rails.logger.info("Subscribed #{self.email} to MailChimp") if result
  end
end
Started POST "/users" for 127.0.0.1 at 2017-07-16 11:19:39 -0400
Processing by Devise::RegistrationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"fk9rxsYldpBguwCqMAJyiqJ/lN2wRLT81EW15AS81hJ4+ZDWtFxlMA5r9x/KiipExFfz80PLmtEJycLnGxgcKw==", "user"=>{"subscription_plan"=>"4", "email"=>"daniel@hotmail.com", "username"=>"dantheman300", "first_name"=>"Daniel", "last_name"=>"Samius", "country"=>"US", "state"=>"PA", "city_or_town"=>"GreenDale", "zip_code"=>"10005", "how_did_you_learn_about_us"=>"Online", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
Unpermitted parameter: :subscription_plan
  SubscriptionPlan Load (1.0ms)  SELECT  "subscription_plans".* FROM "subscription_plans" ORDER BY "subscription_plans"."id" DESC LIMIT $1  [["LIMIT", 1]]
   (0.0ms)  BEGIN
  User Exists (5.0ms)  SELECT  1 AS one FROM "users" WHERE ("users"."id" IS NOT NULL) AND "users"."slug" = $1 LIMIT $2  [["slug", "dantheman300"], ["LIMIT", 1]]
  User Exists (0.0ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2  [["email", "daniel@hotmail.com"], ["LIMIT", 1]]
   (1.0ms)  SELECT COUNT(*) FROM "users" WHERE "users"."provider" = $1 AND "users"."email" = $2  [["provider", "email"], ["email", "daniel@hotmail.com"]]
  User Exists (0.0ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2  [["email", "daniel@hotmail.com"], ["LIMIT", 1]]
  SubscriptionPlan Exists (0.0ms)  SELECT  1 AS one FROM "subscription_plans" WHERE "subscription_plans"."stripe_id" = $1 AND ("subscription_plans"."id" != $2) LIMIT $3  [["stripe_id", "gold"], ["id", 5], ["LIMIT", 1]]
  User Exists (1.0ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2  [["email", "daniel@hotmail.com"], ["LIMIT", 1]]
  User Exists (1.0ms)  SELECT  1 AS one FROM "users" WHERE "users"."username" = $1 LIMIT $2  [["username", "dantheman300"], ["LIMIT", 1]]
   (2.0ms)  ROLLBACK
  Rendering users/registrations/new.html.erb within layouts/application
  Rendered C:/Ruby233/lib/ruby/gems/2.3.0/gems/payola-payments-1.5.0/app/views/payola/transactions/_stripe_header.html.erb (0.0ms) [cache miss]
  SubscriptionPlan Load (1.0ms)  SELECT "subscription_plans".* FROM "subscription_plans" WHERE "subscription_plans"."name" IN ('Silver | $10.00', 'Gold | $15.00')
  Rendered users/shared/_links.html.erb (2.0ms) [cache miss]
  Rendered users/registrations/new.html.erb within layouts/application (138.1ms)
  Rendered nav_partials/_navbar.html.erb (10.0ms) [cache miss]
Completed 200 OK in 2790ms (Views: 1070.0ms | ActiveRecord: 12.0ms)