RailsApps / rails-stripe-membership-saas

An example Rails 4.2 app with Stripe and the Payola gem for a membership or subscription site.

Home Page:http://railsapps.github.io/rails-stripe-membership-saas

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Best way to update plan/reassign credit card in devise edit?

RailsCod3rFuture opened this issue · comments

The user plan and credit card are failing to update when I submit the changes to the form. Its crashing with a 500 error.
Btw, I'm using SubscriptionPlan instead of Plan, to avoid namespace issues on my platform

registrations_controller.rb

 def user_change_plan
   plan = SubscriptionPlan.find_by!(id: params[:user][:subscription_plan_id].to_i)
   unless plan == current_user.subscription_plan
     role = User.roles[subscription_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 => "Plan changed."
     else
       flash[:alert] = 'Unable to change plan.'
       build_resource
       render :edit
     end
   end
 end

users\registrations\edit.html.erb

<div class="update-subscription">
    <%= simple_form_for(resource, as: resource_name, url: user_change_plan_path, :html => {:method => :put, :role => 'form'}) do |f| %>
      <div class="form-group credit-card-label">
        <div class="col-md-4 field card">
          <label>Credit Card Number</label>
          <input id="card_number" type="text" data-stripe="number" class="form-control card-number" maxlength="19" placeholder="Enter your 19 Digit Credit Card Number"/>
          <span class="card_icon" style="margin-top: 0.05em"></span> <br>
          <p class="status"><span class="status_icon"></span><span class="status_message"></span></p>
        </div>
      </div>
      <div class="form-group row">
        <div class="col-md-2">
          <label>Card Expire Date</label>
          <input type="text" data-stripe="exp-month" placeholder="Month" class="form-control">
          <input type="text" data-stripe="exp-year" placeholder="Year" class="form-control">
        </div>
      </div>
      <div class="form-group">
        <div class="col-2">
          <label>Card Security Code</label>
          <input id="card_code" placeholder="cvc" type="text" data-stripe="number" class="form-control"/>
        </div>
      </div>
      <div class="form-group">
        <button class="btn btn-primary-outline" type="submit">Change Subscription Plan</button>
      </div>
      </div>
      <input type="hidden" value="<%= form_authenticity_token() %>" name="authenticity_token"/>
    <% end %>

routes.rb

devise_scope :user do
   put 'user_change_plan', :to => 'users/registrations#user_change_plan'
   authenticated do
     root to: 'user_dashboard#index', as: 'authenticated_user_root'
   end
   unauthenticated do
     root to: 'home#index', as: 'unauthenticated_user_root'
   end
 end

Stack trace

Started PUT "/user_change_plan" for 127.0.0.1 at 2018-11-24 13:01:58 -0500
Processing by Users::RegistrationsController#user_change_plan as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"UTVhe2CIwzvpppGt+QS3K9Qh+OwGbYzlXVkHL5Yn8Pvd6cZ2VhtWV09Rfk3T4bCLRWl1CvEnvImwiMSoNHUnfw==", "user"=>{"subscription_plan_id"=>"4"}, "commit"=>"Change Plan"}
  SubscriptionPlan Load (0.0ms)  SELECT  "subscription_plans".* FROM "subscription_plans" WHERE "subscription_plans"."id" = $1 LIMIT $2  [["id", 4], ["LIMIT", 1]]
  User Load (1.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 2], ["LIMIT", 1]]
  SubscriptionPlan Load (1.0ms)  SELECT  "subscription_plans".* FROM "subscription_plans" WHERE "subscription_plans"."id" = $1 LIMIT $2  [["id", 5], ["LIMIT", 1]]
   (0.0ms)  BEGIN
  SubscriptionPlan Exists (1.0ms)  SELECT  1 AS one FROM "subscription_plans" WHERE "subscription_plans"."stripe_id" = $1 AND "subscription_plans"."id" != $2 LIMIT $3  [["stripe_id", "silver"], ["id", 4], ["LIMIT", 1]]
  User Exists (1.0ms)  SELECT  1 AS one FROM "users" WHERE "users"."email" = $1 AND "users"."id" != $2 LIMIT $3  [["email", "cooler@hotmail.com"], ["id", 2], ["LIMIT", 1]]
  User Exists (0.0ms)  SELECT  1 AS one FROM "users" WHERE "users"."username" = $1 AND "users"."id" != $2 LIMIT $3  [["username", "cooler"], ["id", 2], ["LIMIT", 1]]
   (0.0ms)  ROLLBACK
Completed 422 Unprocessable Entity in 872ms (ActiveRecord: 4.0ms)


  
ActiveRecord::RecordInvalid (Validation failed: Password can't be blank, Password is too weak):
  
app/controllers/users/registrations_controller.rb:44:in `user_change_plan'

Attempting to change only the subscription plan fails also.

<div class="authform">
     <h3>Subscription Plan</h3>
     <%= simple_form_for(resource, as: resource_name, url: user_change_plan_path, :html => {:method => :put, :role => 'form'}) do |f| %>
       <div class="form-group">
         <div class="col-md-3">
           <%= f.label 'Change Monthly Subscription Plan' %>
           <%= f.association :subscription_plan, collection: SubscriptionPlan.user_plan.map {|c| [c.name, c.id]}, label: false, prompt: 'Choose a plan' %>
         </div>
         <%= f.submit 'Change Plan', :class => 'btn btn-primary-outline btn-md' %>
       </div>
     <% end %>
   </div>

One other note: I'm using Rails 5.2 and ruby 2.4.4