Me
Blog about Ruby, Rails, and more!

Using Rails with Yarn on Heroku

2017-08-20

One of thee best features of Rails 5.1 is Yarn support. You can easily manage your javascript dependencies just by using yarn add. It's a breeze.......until you push to Heroku.

Heroku dynos use 'buildpacks' which refers to a specific set of tools that your app has access to during a deploy. If you are deploying a Rails app, your default buildpack will be heroku/ruby.

However, since we are trying to deploy a Rails 5.1 app that needs to run yarn install, you will need to add the heroku/nodejs buildpack. The nodejs buildpack will give your app access to the yarn executable during deployment, meaning that you can run yarn install.

To add the nodejs buildpack to your Heroku app, run heroku buildpacks:add --index 1 heroku/nodejs. From the heroku docs:


    This will insert the Node.js buildpack at the first position in the order of buildpack execution,
    and move the other buildpacks that are ahead of it down one position. Thus the Ruby 
    buildpack will now be the second buildpack to run.


Tell Rspec to only show you green dots

2017-08-20

Rspec offers a handful of different formatting options for test output. The default option is to just show the familiar green dots, yellow stars, and red F's with which rspec users are familiar.

However, you can modify the default formatting option in the test suite itself, which means that a user running rspec spec/foo_spec.rb with no formatting option can end up seeing much more output than expected.

Personally, I just want to see green dots, yellow stars, and red F's. You can force rspec back to the default progress bar format by passing the --format progress option when using the CLI.

That command would look like: ruby rspec spec/foo_spec.rb --format progress

Now, assuming that all your tests are passing, you should just see a neat line of green dots.


Fixing PG::UniqueViolation: ERROR: duplicate key value violates unique constraint

2017-08-13

If you are seeing ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR: duplicate key value violates unique constraint...), it means that active record is attempting to create a record with a primary key that is already in use.

Why is this happening? Postgres keeps track of your current sequence value, which is waht Active Record looks at when it attempts to asssign an id to a new record. In this case, the sequence has been changed without Active Records knowledge.

To fix the issue, we have to tell Active Record to go back and look at the sequence of the table:

ActiveRecord::Base.connection.reset_pk_sequence!('table_name')

Now Active Record should have the correct sequence value, and should be able to assign new id's properly.


Using lambdas with case statements

2017-08-13

Let's be honest, no one likes to see a long chain of if/elsif mucking up a codebase. A nice alternative to long if/elsif chains is to use a case statement. This is easy enough for comparing strings or symbols, but what do you do if you need to actually call methods on your case variable?

For example, imagine you have a rails model with several predicate methods. Lets call our example model Book. Lets assume our Book models has several predicate methods used to determine a books status; fulfilled?, processing?, completed?, and cancelled?.

You can use these predicate methods within a case statement, like so:

new_order = Order.new
case new_order
when -> (order) { order.fulfilled? }
  'your order is filfilled!'
when -> (order) { order.processing? }
  'your order is processing!'
when -> (order) { order.completed? }
  'your order is completed!'
when -> (order) { order.cancelled? }
  'your order is cancelled!'
else
  raise 'UndefinedStatusError'
end

You could also use this to run some code only if a hash has certain keys: ```ruby case myhash when -> (hash) { hash[:keya] } 'hash has keya' wher -> (hash) { hash[:keyb] } 'hash has key_b' end

IMO this definitely looks cleaner than a long chaing of if/elsif statements.


Using define_method to dynamically define predicate methods

2017-07-16

In my last post I demonstrated how class_eval can be used to define predicate methods. You can also define predicate methods in a similar manner using define_method.

Lets take a look at the User class from the previous example:

class User
  POSSIBLE_STATUSES = %w(Active Inactive Disabled Banned)

  attr_accessor :status

  def initialize
    @status = 'Inactive'
  end

  POSSIBLE_STATUSES.each do |status|
    class_eval <<-CODE
      def #{status.downcase}?
        self.status == '#{status}'
      end
    CODE
  end
end

Currently it uses class_eval to dynamically define predicate methods for every possible user status. Lets refactor the User class to use define_method instead.

class User
  POSSIBLE_STATUSES = %w(Active Inactive Disabled Banned)

  attr_accessor :status

  def initialize
    @status = 'Inactive'
  end

  POSSIBLE_STATUSES.each do |status|
    define_method("#{status.downcase}?") do
      self.status == status
    end
  end
end

This will give us a predicate method for every possible status in the POSSIBLE_STATUSES array. We can test each of these methods in irb:

irb(main):039:0> User.new.active?
=> false
irb(main):040:0> User.new.disabled?
=> false
irb(main):041:0> User.new.banned?
=> false
irb(main):042:0> User.new.inactive?
=> true

The default status of a new user is 'Inactive', which we set in the initialize method of our User class. All other predicate status methods return false, since the user can only have one status at a time.

There is a performance benefit to using define_method though, for reasons I will not go into here. However, if you are dynamically defining only a handful of methods you probably won't notice any performance difference, so use whatever syntax you prefer.

If you want to read more about the perforance differences between the two, check out this great post by Aaron Patterson.


Using class_eval to dynamically define predicate methods

2017-07-11

A predicate method ends with ?, and returns true or false

This post will be part one of a two part series about dynamically defining predicate methods with classeval and definemethod.

Often times in a Rails application, you end up storing state in your database. This state usually takes the form ofsome type of status attribute on a model. You end up needing to determine what state a specific instance of that model is in, which is a great use case for class_eval.

For example, if you have a model named User with four possible statuses you could use class_eval in the following manner:


class User
  POSSIBLE_STATUSES = %w(Active Inactive Disabled Banned)

  attr_accessor :status

  def initialize
    @status = 'Inactive'
  end

  POSSIBLE_STATUSES.each do |status|
    class_eval <<-CODE
      def #{status.downcase}?
        self.status == '#{status}'
      end
    CODE
  end
end

This will dynamically define boolean methods on the User class. To test this code, just paste it into an irb session.

You can call the status method on a new user to see the default status, which we set in the initialize method:


irb(main):001:0> User.new.status
=> "Inactive"

Finally, lets test all of our boolean method. There will be one boolean method defined for each status within our POSSIBLE_STATUSES array.


irb(main):001:0> User.new.active?
=> false
irb(main):002:0> User.new.disabled?
=> false
irb(main):003:0> User.new.banned?
=> false
irb(main):004:0> User.new.inactive?
=> true

You can also use define_method in a similar way, which I will go over in my next post.