Save 36% for Black Friday! Learn more

Adrian DeGus

Joined

2,530 Experience
10 Lessons Completed
1 Question Solved

Activity

Posted in How to send different Plan ID's to Stripe?

Just rewatched the video and realized Chris suggested hidden fields as the best solution for this. So I got it working by adding these hidden fields to my Stripe form:

<%= hidden_field_tag(:plan_id, @plan.id) %>
<%= hidden_field_tag(:plan_seats, @plan.seats) %>

And modifying my controller as such:

def create
    @company = Company.friendly.find(params[:company_id])
    @plan_id = params[:plan_id] # <<<<
    @plan_seats = params[:plan_seats] # <<<<

    customer = Stripe::Customer.create(
        email: current_user.email,
        source:  params[:stripeToken],
    )

    subscription = customer.subscriptions.create(
        plan: @plan_id # <<<<
    )

    @company.users.each do |user|
      user.update(
          subscribed_at: Time.now,
          canceled_at: nil
      )
    end

    current_user.update(
                    stripe_id: customer.id,
                    stripe_subscription_id: subscription.id,
                    card_last4: params[:card_last4],
                    card_exp_month: params[:card_exp_month],
                    card_exp_year: params[:card_exp_year],
                    card_type: params[:card_brand],
                    stripe_plan_id: @plan_id, # <<<<
                    invitation_limit: @plan_seats # <<<<
    )

    redirect_to company_path(@company)

  rescue Stripe::CardError => e
    flash[:error] = e.message
    redirect_to company_upgrades_path(@company)
  end

Posted in How to send different Plan ID's to Stripe?

I worked through the Subscriptions with Stripe video and got everything working fine, with a single Plan ID.

Now I'm trying to modify it to work with multiple Plan ID's to give my users payment options.

I created a model to hold all of my plans, with each plan ID matching the plan ID at Stripe, so that I can pull the ID from params to send to Stripe.

The wall I've hit is that I can't seem to actually send the param ID to Stripe.

What am I doing wrong?

subscriptions_controller.rb

def create
    @company = Company.friendly.find(params[:company_id])
    @plan = Plan.find(params[:id]) ### This ID works on #show but can't be found in #create

    customer = Stripe::Customer.create(
        email: current_user.email,
        source:  params[:stripeToken],
    )

    subscription = customer.subscriptions.create(
        # plan: '001' ### This works
        plan: @plan ### This doesn't
    )

    @company.users.each do |user|
      user.update(
          subscribed_at: Time.now,
          canceled_at: nil
      )
    end

    current_user.update(
                    stripe_id: customer.id,
                    stripe_subscription_id: subscription.id,
                    card_last4: params[:card_last4],
                    card_exp_month: params[:card_exp_month],
                    card_exp_year: params[:card_exp_year],
                    card_type: params[:card_brand],
                    stripe_plan_id: @plan, ### Need this to work
                    invitation_limit: @plan.users ### Need this to work
    )

    redirect_to company_path(@company)

  rescue Stripe::CardError => e
    flash[:error] = e.message
    redirect_to company_upgrades_path(@company)
  end

Posted in Just want to say thanks!

Hoping this isn't too cheesy, but I wanted to take a second to thank Chris for taking the time to make all of these invaluable videos here and to the community for helping me find solutions to problems that I couldn't find elsewhere.

1 year (and 2 days) ago I decided to learn how to code so that I could make my own project management tool. None of the others like Trello or Wrike or Asana gave me a clear enough insight into the overall operations of my company or into the current/upcoming workload of my team. Also, I've always struggled with RSI/Carpal Tunnel type pain and the number of steps these other tools required just to accomplish basic things was ridiculous. 7 clicks just to reschedule a task and return to the page you were just on, really?! lol

Anyways, I managed to finish my app, https://nuvro.com/, something I couldn't have done without GoRails. I not only learned how to implement vital features but learned a ton about rails and coding in general.

Posted in Chartkick doesn't load on Heroku?

nm, found the fix. I had to include the chartkick js tags into the header of my application layouts while including my other js files at the very end of the body, to prevent breaking my wysiwyg editors.

Posted in Chartkick doesn't load on Heroku?

I setup a few charts in my app using Chartkick, which work fine in development but not in production. I have the same "Chartkick is not defined" issue as this guy https://github.com/ankane/chartkick/issues/347 but what fixed it for him didn't for me. I even tried possible fixes found on other SO threads, with no luck.

Anyone have the same problem on Heroku?

Posted in PDF Receipts not working

That did the trick!

Posted in PDF Receipts not working

When I used resources :charges in my routes it threw an exception due to the lack of a charge ID. It's because of this that I changed my route to resource :charge

Posted in PDF Receipts not working

I just finished working through the pdf receipts video but can't get it to work. I have the webhook working and all charges are displayed properly, but the link to the pdf 404's.

Can you see where I went wrong?

# config/initializers/stripe.rb

class RecordCharges
  def call(event)
    charge = event.data.object

    user = User.find_by(stripe_id: charge.customer)

    user.charges.create(
                    stripe_id: charge.id,
                    amount: charge.amount,
                    card_last4: charge.source.last4,
                    card_type: charge.source.brand,
                    card_exp_month: charge.source.exp_month,
                    card_exp_year: charge.source.exp_year
    )
  end
end

StripeEvent.configure do |events|
  events.subscribe 'charge.succeeded', RecordCharges.new
end


# charge.rb

belongs_to :user

def receipt
    Receipts::Receipt.new(
        id: id,
        product: "Nuvro",
        company: {
            name: "Nuvro LLC",
            address: "2040 S Alma School Rd Suite 1-484\nChandler, AZ 85286",
            email: "support@nuvro.com",
            logo: Rails.root.join("app/assets/images/nuvro-50.png")
        },
        line_items: [
            ["Date",           created_at.strftime('%B' '%d,' '%Y')],
            ["Account Billed", "#{user.first_name} #{user.last_name} (#{user.email})"],
            ["Product",        "Nuvro"],
            ["Amount",         "$#{amount / 100}.00"],
            ["Charged to",     "#{card_type} (**** **** **** #{card_last4})"],
            ["Transaction ID", uuid]
        ]
    )
  end


    # user.rb

    has_many :charges


# charges_controller.rb

def show
    @charge = current_user.charges.find(params[:id])
    respond_to do |format|
      format.pdf {
        send_data @charge.receipt.render,
                  filename: "#{@charge.created_at.strftime("%m-%d-%Y")}-nuvro-receipt.pdf",
                  type: "application/pdf",
                  disposition: :inline
      }
    end
  end


    # routes.rb

    resource :charge # charges#show


    # views/companies/edit.html.erb

    <% current_user.charges.each do |charge| %>
    ....
    <%= link_to "View Receipt", charge_path(@charge, format: :pdf) %>

    ...
    <%= link_to "View Receipt", charge_path(charge, format: :pdf) %> # tried this, didn't work

I'm missing something obvious, I just know it :)

Posted in Stripe - Question about canceling accounts

Thanks Chris, webhooks were indeed the answer.

Posted in Stripe - Question about canceling accounts

I just finished following the screencasts on setting up Stripe, everything went well!

I have my app setup to cancel accounts :at_period_end so that subscribers can continue accessing content through the duration of their subscription.

Question is, how to postpone the removal of their subscription_id from the users table also :at_period_end?

Thanks for the direction Chris! My activity feed is working perfectly now.

I hadn't realized that I was hitting the db twice, using assign_attributes now and am going to use transactions for notifications next.

I got comments to create properly by noticing the mistakes I had made with:

@comment = current_user.events.create(action: "commented", eventable: @task) 

It should have been:

@task.events.create(action: "commented", eventable: @task, user_id: current_user.id)

Abhinay, I personally decided against public_activity because I couldn't get it to work properly with my nested resources. Activity feeds from scratch gave me the control I needed to tweak everything to work with my particular app. Plus I had already setup notifications using Chris' screencast and the activity feed works similarly, really helped keep things streamlined.

After spending more time on this I can see that using the notifications system for an activity feed isn't going to work very well. So moving onto implementing 'activity feeds from scratch'...

I just need to be able to create the events from within controller actions.

Here is what I tried in my comments_controller:

@task_id = params[:task_id]
@comment = Comment.new(comment_params)
@comment.update_attributes(task_id: @task_id, user_id: current_user.id)
@comment.save!

@comment = current_user.events.create(action: "commented", eventable: @task) 

(@task.users.uniq - [current_user]).each do |user|
      Notification.create(getter: user, doer: current_user, action: 'commented', notifiable: @task)
    end

But this prevents comments from being created for some reason.

What am I doing wrong?

I worked through https://gorails.com/episodes/improving-in-app-notifications yesterday and it works great.

I tried to use this same system create activity feeds for my different models, but ran into a problem. Duplicates. Every activity/notification contained (seemingly) duplicate records, most likely due to the fact that a notification record is created for each user. So when I iterate through all notifications it lists out what appear to be duplicates.

  1. Is there any way to single out one record for each event? I tried pulling out records only for actors, but it didn't work.

As an alternative I also tried working through https://gorails.com/episodes/activity-feed-from-scratch but couldn't figure out how to create event records from within controller actions. I tried this in my comments_controller but it prevented comments from being created:

@comment = current_user.events.create(action: "commented", eventable: @task)
  1. What's the correct way to create events from within controller actions?

Option 1 would be awesome, option 2 would be great... option 3 (public_activity gem or getstream.io would suck).

Any help is appreciated :)

Posted in How to delete records in a join table?

Thanks Chris!

I actually had a document_attachments controller setup and was getting unilitialized constant errors, which through research I learned could be due to a routing conflict with Refile due to the similar name.

I'll try this again with a different name, maybe document_uploads, and hope the convention over configuration thing doesn't bite me.

Posted in How to delete records in a join table?

I'm using Refile for uploads and am having a tough time figuring out how to delete individual files. I need to display a delete link under each thumbnail, so my first thought was to do something like:

<% @document.document_attachments.each do |doc| %>
         <%= link_to attachment_image_tag(doc, :file), attachment_url(doc, :file), target: '_blank' %><br />
             <%= link_to 'Delete', document_attachment_path(doc, :file), method: :delete %>
<% end %>

I tried different paths/routes/controllers but nothing works. Maybe it's because I'm using a document_attachments join table?

class Document < ApplicationRecord
  has_many :document_attachments, dependent: :destroy
  accepts_attachments_for :document_attachments, attachment: :file, append: true
end

class DocumentAttachment < ApplicationRecord
  belongs_to :document  
  attachment :file
end

What's the best way to get these delete links working?

Posted in How to write a conditional in a create action?

Decided to go with Refile instead of Shrine. I found it easier to work with and was able to implement everything I needed in two days, while I was still wrestling with Shrine after two weeks. I probably just lack the experience that Shrine requires.

Posted in How to write a conditional in a create action?

Okay thanks for the direction guys, I'll start looking into this to see how to get it done.

Posted in How to write a conditional in a create action?

I recently worked through the 4 episodes here on direct uploads to S3 with shrine.

I have things setup to upload both images and documents and am now trying to write a conditional to create either an associated image or document record depending on whether the uploaded file is an image or a document (so that I only need one form for users). This is what I have so far, but I feel I might be working in the wrong direction.

Models:

class Project < ApplicationRecord
  has_many :project_images, as: :attachable
  has_many :project_documents, as: :attachable
end

class ProjectImage < ApplicationRecord
  include ImageUploader[:image]
  belongs_to :attachable, polymorphic: true
end

class ProjectDocument < ApplicationRecord
  include DocumentUploader[:image]
  belongs_to :attachable, polymorphic: true
end

Project Images Controller:

def create
    @project = Project.find(params[:project_id])
    @project_id = params[:project_id]
    @project_image = @project.project_images.build(project_image_params)
    @project_image.update(user_id: current_user.id, project_id: @project_id)

    respond_to do |format|
      if @project_image.save
        format.html { redirect_to @project }
        format.json { render :show, status: :created, location: @project }
      else
        format.html { render :new }
        format.json { render json: @project_image.errors, status: :unprocessable_entity }
      end
    end
  end

Project Documents Controller:

def create
    @project = Project.find(params[:project_id])
    @project_id = params[:project_id]
    @project_document = @project.project_documents.build(project_document_params)
    @project_document.update(user_id: current_user.id, project_id: @project_id)

    respond_to do |format|
      if @project_document.save
        format.html { redirect_to @project }
        format.json { render :show, status: :created, location: @project }
      else
        format.html { render :new }
        format.json { render json: @project_document.errors, status: :unprocessable_entity }
      end
    end
  end

Project View:

<%= form_for ([@project, @project_image]) do |f| %>
    <p>
      <%= f.file_field :image, multiple: true, name: 'project_image[image]' %>
    </p>
<% end %>

I started by trying to write a conditional in project_images#create but couldn't define how an uploaded document would differ from an image. Maybe I can grab the file extension on the way in somehow?

Then I moved onto another approach, but I'm stuck here as well:

Attachment Model:

class Attachment < ApplicationRecord
  belongs_to :attachable, polymorphic: true
  belongs_to :project
end

Attachments Controller:

class ProjectAttachment < ApplicationRecord

  def create
    @project = Project.find(params[:project_id])
    @project_id = params[:project_id]
    @attachment = @project.attachments.build(attachment_params)   # @object inserts here somehow?
    @attachment.update(user_id: current_user.id, project_id: @project_id)

    respond_to do |format|
      if @attachment.save
        format.html { redirect_to @attachment.project }
        format.json { render :show, status: :created, location: @attachment }
      else
        format.html { render :new }
        format.json { render json: @attachment.errors, status: :unprocessable_entity }
      end
    end
  end

  private

  def create_object
    id = params[:project_document_id] || params[:project_image_id]

    model = ProjectDocument if params[:project_document_id]
    model = ProjectImage if params[:project_image_id]

    @object = model.find(id)
  end

end

Project View:

<%= form_for ([@project, @attachment]) do |f| %>
    <p>
      <%= f.file_field :image, multiple: true, name: 'attachment[image]' %>
    </p>
<% end %>

Am I on the right track with either of these attempts?

Posted in Multiple File Uploads with Shrine Discussion

One small issue I'm running into.. since photos are displayed after uploading with js it's necessary to refresh the page for rails handling to kick in. For example, new images are not linked to their own show pages until a refresh. Also, the max width setting is removed after a refresh, since rails takes over.

Is there any way to handle all display options with rails from the start, so that no page refresh is necessary?

Posted in has_many :through association woes

Your suggestion above worked to set the user_id in my project_assignments join table.

After tinkering with this for longer I think the other problem I'm having is being caused by trying to use two join tables, one for projects and the other for tasks.

I'm going to stick with the one join table, see if I can use it to assign projects to users and then later try to add a task_id parameter to the same table, if needed, to assign tasks.