Iacutone.rb

coding and things

JQuery beforeSend Function

| Comments

I have a form which submits a comment via AJAX. The app was throwing validation errors if there was no value in the comment field. My initial solution was to disable the submit button if the comment is blank. However, using the beforeSend function provides a cleaner solution.

1
2
3
4
5
6
7
8
9
10
11
12
  comment = ('.form-field-comment').val()

  $.ajax
    type: 'POST'
    dataType: 'script'
    url: comment_form.attr('action')
    data:
      comment:
        body: comment
    beforeSend: () ->
      if comment is ''
        return false; # do this instead of disabling the submit button 

With the above code, the comment form is never posted if the comment is blank.

ActiveRecord None

| Comments

The .none class method was introduced in Rails 4.0.2 and is helpful when returning a blank array will break.

1
2
3
4
5
Organization.none.paginate(page: '1')
 => #<ActiveRecord::Relation []>

[].paginate(page: '1')
 => NoMethodError: undefined method `paginate' for []:Array

Helpful Links

none

Submitting a Get Request in Rails

| Comments

For the error “WARNING: Can’t verify CSRF token authenticity”, add a CSRF token.

_form.html.haml
1
2
3
4
= form_tag some_path(@organization), method: :get do
  = hidden_field_tag :authenticity_token, form_authenticity_token # this needs to be added!
  = submit_tag "View"
  = link_to_function 'Export', "Javascript function which posts to another route"

The top-level block contains method: :get which doesn’t auto-add the needed authenticity_token.

Helpful Links

Understanding the Rails Authenticity Token

RSpec Example Blocks

| Comments

I recently discovered an interesting test pattern; defining variables in before and after hooks in the rails helper.

rails_helper.rb
1
2
3
  config.before(:example, hook: true) do
    @hook = 'before hook'
  end
some_spec.rb
1
2
3
4
5
6
7
8
  RSpec.describe "some variable I need" do

    describe 'my hook', hook: true do
      it 'runs the hook' do
        expect(@hook).to eq 'before hook' # returns true
      end
    end
  end

A Real Example

Let’s say we are testing a controller and want to make sure only an admin has access to specific views.

rails_helper.rb
1
2
3
4
5
6
7
8
9
  config.before(:example, admin_signed_in: true) do
    current_user_double = Test::User.new :admin => true
    allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(current_user_double)
  end

  config.before(:example, user_signed_in: true) do
    current_user_double = Test::User.new :admin => false
    allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(current_user_double)
  end

When setting admin_signed_in to true in a describe block, we have access to an admin user. I think it is cleaner to set up these users in a hook instead of a shared context or explicitly in the spec.

Helpful Links

Hooks

Using Mocks to Test Mailers in RSpec

| Comments

I was in the situation where I needed to test the delivery of emails based on specific sets of events. I began testing by inspecting sent emails in ActionMailer::Base.deliveries. However, this method of testing felt verbose and sloppy.

RSpec mocks is a great solution when you need to test that a specific method was called. In my case, I want a fundraiser to receive an email after a campaign goal is reached.

donation_funding.rb
1
2
3
4
5
6
7
8
9
10
11
12
class DonationFunding
  attr_reader :donation

  def initialize(donation)
    @donation = donation
  end

  def fund
    # do some work
    CampaignMailer.notify_curator_campaign_goal_reached(donation)
  end
end
donation_funding_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  before do
    donation.amount = campaign.goal_amount + 1
    donation.save!
  end

  # Make a donation that exceeds the funding goal

  let!(:funder) {
    funder = DonationFunding.new donation
    funder
  }

  # set up the donation for funding

  it 'sends email goal amount reached email to the curator' do
    expect(CampaignMailer).to receive(:notify_curator_campaign_goal_reached).and_call_original
    funder.fund
  end

  # Expect a CampaignMailer.notify_curator_campaign_goal_reached email to be sent

The definition for the method and_call_original is, “You can use and_call_original on the fluent interface to "pass through” the received message to the original method.“ What exactly does this mean? It means that when I call funder.fund, I expect CampaignMailer.notify_curator_campaign_goal_reached to be called.

Helpful Links

Calling the original method

ENV Variables in XCode

| Comments

Setting ENV variables in XCode in not straighforward. I have broken down how to accomplish setting up an ENV variable in the following videos and code example.

Make a new conifuration file and set any ENV variables you need.

In the debug environment, use the debug.xcconfig file. Then, assign the value to something, in this case, SignUpUrl corresponds with the SIGN_UP_URL, which is set to localhost:4567/sign_up.

SignUpController.swift
1
2
  var info:[NSObject:AnyObject] = NSBundle.mainBundle().infoDictionary!
  var sign_up_url = info["SignUpUrl"] as! String

The sign_up_url variable is set to localhost:4567/signup.

Helpful Links

Configuring ENV Variables in XCode

Shared Contexts With RSpec

| Comments

In the past, I used traits with my factories. Below is a simple example of defining a trait:

Using traits

donations_factories.rb
1
2
3
4
5
6
7
8
9
10
11
  FactoryGirl.define do
    factory :donation do
      trait :with_amount do
        amount 10
      end

      trait :no_amount do
        amount 0
      end
    end
  end

An example spec:

donation_spec.rb
1
2
3
4
5
6
7
8
9
10
  RSpec.describe 'Donation Matching', :type => :model do

    context 'with an amount' do
      let(:donation) { create(:donation, :with_amount) }
    end

    context 'with no amount' do
      let(:donation) { create(:donation, :no_amount) }
    end
  end

However, I believe that using a shared context is a clearer approach. Defining the amount in a shared context and overriding the amount allows more control over testing use cases.

Using a shared context

donation_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  require 'support/shared_contexts/donor_with_donation_context'

  RSpec.describe 'Donation Matching', :type => :model do
    include_context 'a donor with a donation'

    context 'with an amount' do
      // donation.amount == 10 (defined in the shared context)
    end

    context 'with no amount' do
      let(:amount) { 0 }
      // donation.amount == 0
    end

    context 'with a gnarly' do
      let(:amount) { 09709780 }
    end
  end
spec/support/shared_contexts/donor_with_donation_context.rb
1
2
3
4
5
  RSpec.shared_context 'a donor with a donation' do
    let(:amount) { 10 }

    let(:donation) { create(:donation, amount: amount) }
  end

I especially like the shared context approach because you can have shared context and redefine attributes as needed in specs.

Auto Layout Xcode for Navigation Bar

| Comments

Finding auto layout information is difficult. The steps below pin a navigation bar to the top of the screen for all iOS devices.

Steps

  • Make sure “Navigation Bar” is selected on the left menu
  • Click the “Pin” button on the bottom right corner
  • Click the top, left and right constraints
  • Click the Height constraint
  • Add the 4 contraints

The above steps “pin” the navigation bar object to the top of the view and stretch the navigation bar to the sides of the view. The height constraint keeps a static height for the navigation bar.

Helpful Links

Auto Layout Basics

Prototypes and Constructors in Javascript

| Comments

I usually do not need to write code using neither constructors nor prototypes in Javascript. So, I always forget how to write them when I need to use them.

Constructor

1
2
3
4
5
6
7
8
9
10
  Say = function(){
    this.hello = function() {
      return "Hello";
    }
  }

  var say = new Say();
  say.hello()

  // "Hello"

Prototype

1
2
3
4
5
6
7
8
9
  function Say() {}
   Say.prototype.hello = function() {
    return "Hello";
  }

  var say = new Say();
  say.hello()

  // "Hello"

Helpful Links

Use of ‘prototype’ vs. ‘this’ in JavaScript?

Advantages of using prototype, vs defining methods straight in the constructor?

Shell Function

| Comments

I have been using youtube-dl every week. The application is a “Small command-line program to download videos from YouTube.com and other video sites.” It’s super useful. However, it default downloads to the current terminal directory. Let’s write a simple shell script in order to place all downloaded files from youtube-dl in the same directory.

.zshrc
1
2
3
4
5
6
function mp3 {
  # Download all of the things to /Downloads

  youtube-dl --default-search=ytsearch: \
             --output="Downloads/%(title)s.%(ext)s" "$*"
}

The “$” signifies the string following mp3, the example below, “$” is the URL arument.

1
  mp3 https://www.youtube.com/watch\?v\=9fYeiGeuTFA

Now I can run the above script in order to download the video from the youtube URL.!

Helpful Links

youtube-dl