Austin Story

Ruby, Rails and Javascript Blog

Powered by Genesis

Quickly Demo Ruby on Rails Issues in a Single File

November 29, 2020 By Austin Story Leave a Comment

I saw a really great issue in the Rails repo where someone was able to demonstrate a full rails issue without having to recreate an entire application. I thought this was fantastic because I have never setup an example like this before and think it would save a ton of time when iterating on ideas or reproducing issues.

# frozen_string_literal: true

# 1. Add any gems that you may need inline
require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |<em>repo</em>| "https://github.com/#{<em>repo</em>}.git" }

  # Activate the gem you are reporting the issue against.
  gem "rails", github: "rails/rails", branch: "master"
  gem "sqlite3"
  gem "pry"
end

require "active_record"
require "minitest/autorun"
require "logger"
require "pry"

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :posts, force: true do |<em>t</em>|
    t.string :name
    t.text :description
    t.datetime :routing_start_date
    t.datetime :routing_end_date
  end

end

class Post < ActiveRecord::Base
  has_many :comments
end

class BugTest < Minitest::Test
  def test_association_stuff
    post = Post.create!(name: [])
    post.routing_start_date = DateTime::Infinity

    assert_equal DateTime::Infinity, 
    post.routing_start_date
  end
end

Filed Under: Programming, Ruby, Ruby on Rails

Creating private_attr_reader in Ruby

February 16, 2016 By Austin Story Leave a Comment

In my current project we use a whole lot of plain ruby objects. One day I was looking at them and noticed that we follow this pattern for just about everything.
[ruby]
module MyModule
class MyClass
attr_reader :params

def initialize(params:)
@params = params
end
def call
params.do_things
end
end
end
[/ruby]

The params attr_reader is used so that we don’t have to use @params throughout the object. I got used to this format and like that my ide looks better without all the @vars everywhere. But I think that it is a false contract. The public method for our objects is `call` and is all that we ever intend for someone else to use. However, the user of attr_reader says that this is a public method.

To get around this, i decided to add a quick patch so that we could still have the use of the params method locally for instance variable lookup but keep it private so that noone accidentally starts using it only for us to change it in the future.

Here is the patch I added to Object. I didn’t go all the way down to Kernel because all of our objects inherit from Object.

[ruby]
class Object
def self.private_attr_reader(*args)
args.each do |arg|
define_method(arg) { instance_variable_get("@#{arg}") }
private arg
end
end
end
[/ruby]

After adding this patch to Object we can now do this in our object and var1 and var2 would both be have attr_readers that are private to the class.

[ruby]
private_attr_reader :var1, var2
[/ruby]

Filed Under: Ruby, Ruby on Rails Tagged With: Metaprogramming, monkey patching, ruby

Digging Stripe using Map and Select

January 7, 2016 By Austin Story Leave a Comment

Had a client who had a bad subscription plan in their stripe account that was applied over a year ago.  They have enough volume that it didn’t make sense to go through the web admin to clean up the data so we cleaned it up using the Stripe ruby gem.  Here is the process that I went through to discover the correct commands to issue.

To start, this was a promotional amount that was only applied for a few days in january for the start of the year.  So off the bat I wanted to narrow it down to the related customers.

[ruby]
users = User.where("created_at &gt;= ?", 1.year.ago).where("created_at &lt;?", 330.days.ago)

paying_users = users.where.not(stripe_customer_id: nil)

customer_ids = users.map(&:stripe_payment_id)
[/ruby]

Now that we had the customer ids from tripe i wanted to see what the data looked like

[ruby]
Stripe::Customer.retrieve(customer_ids.first)
[/ruby]

the Stripe::Customer that is returned looks and acts like an open struct or hashie mash. So you can call methods on it similar to javascript objects in order to get values of a key that is in the object.

I didn’t know the specific name of the subscription (didn’t have web access). So needed to discover what it was called. I remembered it had the word special in it.

Next is to find the specific customers that we need to look at

[ruby]
stripe_customers = customer_ids.map{|c| Stripe::Customer.retrieve(c)}
stripe_customers.select(&:subscription).map{|c| c.subscription.plan.id}.uniq
[/ruby]

This returns an array of [‘premium’, ‘othersubscriptions’,….,’newyearsspecial’]. So i know that it is the newyearsspecial that i need to update.

[ruby]
special_customers = stripe_customers.select(&:subscription).select{|c| c.subscription.plan.id == ‘newyearsspecial’}

special_subscriptions = special_customers.map{|c| c.subscription.id}

special_subscriptions = special_customers.map(&:subscription)
[/ruby]

The next part is a little vague, in the documentation it says to set the ‘at_period_end’ parameter to true in order to delete it and keep it active until the end of the subscription, so i just did both.

[ruby]
special_subscriptions.each do |subscription|
subscription.at_period_end = true
subscription.delete(at_period_end: true)
end
[/ruby]

Now all of the subscriptions will expire at the end of the year, Yeah!

Filed Under: Ruby on Rails, Stripe Tagged With: API, ruby, Stripe, Stripe APi, Stripe ruby

  • 1
  • 2
  • 3
  • …
  • 7
  • Next Page »

Categories

  • AngularJS
  • Books
  • Devise
  • Elasticsearch
  • ES6
  • Information Security
  • Integrations
  • Javascript
  • Linux
  • Minitest
  • PhoneGap
  • Programming
  • React
  • Redux
  • Ruby
  • Ruby on Rails
  • Stripe
  • Testing
  • Theory
  • TypeScript
  • Uncategorized
  • Vue
  • Webpack