Add multiple records to database on product purchase

Viewed 48

Edit #1

Here is what I am trying in the payments controller to create the CourseModulesUser

CourseModules.count do
  CourseModulesUser.create.times(
    course_module_id: @course_module_id,
    courses_user_id: @courses_user_id,
    complete: false
  )
end

I have a course modules but in order to create the users I need to be able to count the modules for the course bought and then create the records in the CourseModulesUser grabbing the course_user_id and also the course_module_id.

image

Orginal Question

Scenario:

I have courses and modules, and when a user purchases the course a user gets created for that course (kind of like an enrollment), however, when the course gets purchased I also want the modules to go into a separate table taking in the course_module_id and the courses_user_id.

However, there are multiple modules per course,

Here is the payments controller

class PaymentsController < ApplicationController
  before_action :authenticate_user!

  def create
    token = params[:stripeToken]
    @course = Course.find(params[:course_id])
    @user = current_user

    begin
      charge = Stripe::Charge.create(
        amount: (@course.price*100).to_i,
        currency: "gbp",
        source: token,
        description: params[:stripeEmail],
        receipt_email: params[:stripeEmail]
      )

      if charge.paid
        Order.create(
          stripe_id: charge.id,
          course_id: @course.id,
          user_id: @user.id,
          total: @course.price,
          card_last4: charge.source.last4,
          card_type: charge.source.brand,
          card_exp_month: charge.source.exp_month,
          card_exp_year: charge.source.exp_year
        )

        CoursesUser.create(
          course_id: @course.id,
          user_id: @user.id,
          complete: false
        )

        flash[:success] = "Your payment was processed successfully"
      end

    rescue Stripe::CardError => e
      body = e.json_body
      err = body[:error]
      flash[:error] = "Unfortunately, there was an error processing your payment: #{err[:message]}"
    end

    redirect_to course_path(@course)
  end
end

Here is where I have the course user being created

CoursesUser.create(
  course_id: @course.id,
  user_id: @user.id,
  complete: false
)

and this works

image

But I have a separate table for course_modules_users

image

So let's say for example I have a course with two modules, and a course with the id of 1 and a user with the id of 1 I would ideally have something like this

id  course_module_id   courses_user_id   complete
1   1                  1                 false
2   2                  1                 false

So when a user purchases the course both modules should have records created in this table.

Here is what I have for the model

class CourseModulesUser < ApplicationRecord
  belongs_to :course_module
  belongs_to :courses_user

  after_update :update_courses_user, if: :completed?

  def siblings
    self.class.where(courses_user_id: self.courses_user_id)
  end

  def completed!
    self.update_attributes(complete: true)
  end

  def completed?
    siblings.all?(&:complete?)
  end

  def update_courses_user
    self.courses_user.completed!
  end
end

But I assume this is just a simple edit to the PaymentsController.

1 Answers

There are two ways that I could do this depending on how and when do I want the records for the CourseModelUser to be created:

  1. I want the records to be created along with the creation of CourseUser (if CourseUser doesn't get created due to any reason then CourseModuleUser shouldn't get created as well). This code goes along with the CourseUser creation in your payments controller.

    ActiveRecord::Base.transaction do
      CoursesUser.create(
        course_id: @course.id,
        user_id: @user.id,
        complete: false
      )
      module_ids = CourseModule.where(course_id: @course.id).pluck(:id)
      module_ids.each do |module_id|
      CourseModuleUser.create(
        course_module_id: module_id,
        courses_user_id: @user.id,
        completed: false
      )
      end
    end
    
  2. I just want the CourseModuleUser to be created after the creation of CourseUser model. This code goes inside the CourseUser model.

    after_commit :create_couser_module_user
    
    def create_module_user
      module_ids = CourseModule.where(course_id: self.course_id).pluck(:id)
      module_ids.each do |module_id|
      CourseModuleUser.create(
        course_module_id: module_id,
        courses_user_id: self.id,
        completed: false
      )
    end
    

Note: The answer assumes you've the following model structure:

class Course
  ..
  has_many :course_modules
  ..
end

class CourseModule
  ..
  belongs_to :course
  ..
end
Related