rails-stripe-membership-saas
rails-stripe-membership-saas copied to clipboard
Best way to update plan/reassign credit card in devise edit?
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", "[email protected]"], ["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