Search

Sara Trice

Just a programmin', bellydancin', cake bakin' kinda girl

React, tcomb-form, and date fields

Setting my first date field up in tcomb-form, I followed the docs and used tcomb.Date as the field type:

const Person = t.struct({
  name: t.String,
  surname: t.String,
  email: t.maybe(t.String),
  age: t.Number,
  rememberMe: t.Boolean,
  birthDate: t.Date // a date field
});

Except that gave me this nightmarishly ugly dropdown date format:
Screen Shot 2018-07-11 at 11.20.58 AM

Which accepts a Date object as its value – which this form makes really difficult since if you’re updating on form change, it tries to make a Date object after each change, which results in a lot of invalid dates. Fun.

Even more fun, the values in the month dropdown are in a 0-based array, meaning that when you pick January, you get “0” as your month value, which as you can guess, results in an invalid date.

After some headdesking, I discovered that if you designate the field’s tcomb type as a string and pass the HTML5 “date” type to the field in the form options, you get something a lot prettier (in this example I am using Bootstrap):

 fields: {
   birthDate: {
     label: 'Birth Date',
     type: 'date'
   }
}

Making this a lot easier to deal with on the front and back end.

Quickie: Creating a new EC2 instance with the AWS-SDK for Ruby version 2

Because the documentation for the version 2 SDK has made this incredibly unclear, here you go.

ec2 = Aws::EC2::Client.new(region: 'us-west-2')
res = Aws::EC2::Resource.new(client: ec2)

#remove dry_run: true from the parameters to actually create an instance
inst = res.create_instances(image_id:'ami-123456', min_count:1, max_count:1, instance_type: 't1.micro', dry_run: true)

Some helpful methods on the instance returned:
inst.public_ip_address
inst.state
inst.data
To stop the instance:
ec2.stop_instances(instance_ids:[inst.id])

To start the instance after stopping:
ec2.start_instances(instance_ids:[inst.id])

To terminate the instance:
ec2.terminate_instances(instance_ids:[inst.id])

Bye Bye, Silicone Bakeware

I received the America’s Test Kitchen Family Baking Book for Christmas this year, and while leafing through it, I came across the “10 Baking Gadgets You Don’t Need.” First on the list was “silicone bakeware.”

What? Are you kidding? Nothing sticks to it! And … well ok, I’ll bite. Why not? “In our testing, we found that plastic doesn’t conduct heat very well and muffins and cakes did not brown properly.” I thought I’d try a test of my own, so this morning I made up a batch of banana chocolate chip muffins and made one half in my silicone bakeware and the other half in my trusty ol’ metal muffin pan.

 

muffins

The bottoms aren’t shown here, but the bottom of the muffin baked in the metal pan was nicely browned, while the bottom of the muffin baked in the silicone pan looked as pale and anemic as its top did. The sides of the silicone-pan muffin seemed almost burnt as well. That’s enough to convince me.

One thing I have found the silicone muffin pans good for, though, is freezing portions of chicken stock in pucks for easy storage. Other than that? I think I’m done with silicone.

Om Nom Cornbread

I love Jiffy brand cornbread mix. I like to keep a few boxes on hand at all times. It’s great with soups, chili, stew – most hearty American meal-in-a-bowl foods can benefit from a side of cornbread. It’s probably too sweet for some tastes, but I like a sweeter cornbread. (Hey, I never said I was a real southerner. I only lived there 9 years.)

Now, I don’t begrudge the Jiffy company at all. In fact, I support them whenever possible because they are a good company that treat their employees right and sell an honest product. But sometimes I forget to pick some up, or I run out, or they’re out at the store.  So I went poking around for a copycat recipe.  Turns out it’s not really that hard.

It’s not going to taste exactly like the Jiffy mix as written, because they use lard in the mix, and the below uses oil. Don’t freak out (unless you’re a vegetarian?), because lard probably isn’t as evil as you think it is.

Corn Muffin Mix
2/3 cup all-purpose flour
1/2 cup yellow cornmeal
3 tablespoons granulated sugar
1 tablespoon baking powder
1/4 teaspoon salt

Mix this up and store in a  sandwich-size bag. Makes about 1 1/3 c. (8.5 oz) mix.

To make, add: 
2 tablespoons vegetable oil
1 egg
1/3 cup milk

(If you have a recipe calling for a box of Jiffy Cornbread mix, add the “mix” above and the oil.)

To bake, beat the egg with the milk and oil, then fold into the mix until moistened. (If it seems too thick, add a little more milk.) Bake in a 400°F oven in a paper-lined (or use non-stick cooking spray) muffin tin. Makes 6 muffins.

I like adding 1/2 c. cheddar cheese and a can of green chiles before baking.

Copying all Devise emails to Salesforce

I’ve had the “joy” of working with Salesforce.com in the last year or so. When users receive emails from my application, the sales department wants to know about it, including anything that Devise sends (account confirmations, password resets, etc.).

Setting this up is fairly simple. I’m using Devise 3.1.1 in this instance.

First, create a custom mailer:

rails generate mailer CustomDeviseMailer

Then, to config/initializers/devise.rb, add this line:

config.mailer = "CustomUserMailer"

Finally, change app/mailers/custom_devise_mailer.rb to look like this:

class CustomDeviseMailer < Devise::Mailer
  def headers_for(action, opts)
    if Rails.env.production?
      salesforce_bcc_email = "(your Email to Salesforce address)"
    else
      salesforce_bcc_email = "salesforce_bcc_email@mailinator.com"
    end

    super.merge!({bcc: salesforce_bcc_email})
  end
end

If you need to know where your Salesforce BCC email is:

  1. login to Salesforce
  2. In the top bar click your name, choose “Setup” from the menu
  3. Under “Personal Setup” in the left sidebar, click “Email”
  4. Under the email menu you just expanded, click “My Email to Salesforce”
  5. On that page it’s highlighted with a bright yellow box

Kudos to this StackOverflow question for getting me all fixed up in Devise 3.

Tech and feminism

Anyone who knows me would know that I am not particularly militant when it comes to feminism. I am not a man-hater. I like men. I have many menfriends. I married one. I think they’re neat.

But crap like this happens, and I have to say something: http://stoptechfeminism.tumblr.com/

Talking about acts of sexual assault at tech conferences (which is apparently what engendered the above tumblr) does not equal looking for a sacrificial lamb. It is addressing a very real problem in the culture, the culture many of us belong to. And people need to know that when acts of sexual assault or harassment happen in our culture, there are very real consequences, not only to the people involved, but to the community at large.

Many of us want our culture to expand and include all kinds of different people with new, amazing ideas and different ways of thinking. People do not join a community in which they feel threatened from the get-go. We do not need the talent pool to stagnate, people. Also? Comparing feminists to the Westboro Church is not doing you any favors.

Sidekiq on Engine Yard using a Redis utility instance

So I’ve been running Sidekiq on an Engine Yard instance for a while, but haven’t updated the setup since it was installed. I wanted to fire up a utility instance to run Redis on to take some of the load off the master application instance, so time to dig in.

First thing I did was to update my fork of the ey-cloud-recipes repo. The fabulous Jim Neath has updated the Sidekiq recipe and it’s much better than the old one.

Most of the instructions here will get you where you need to be:
https://github.com/engineyard/ey-cloud-recipes/tree/master/cookbooks/sidekiq

However, it won’t have you connecting to Redis on a utility instance. It’ll have you connecting to redis on localhost or maybe on your database instance, which is fine if your load isn’t heavy.

Let’s fire up a Redis utility instance (in other words, go to your app environment in EY, click “Add”, select utility instance, and name it “redis”). Note that if you want to run sidekiq on a utility instance as well instead of your application instance, fire up an additional utility instance named “sidekiq”.

In your cookbooks/main/recipes/default.rb cookbook, uncomment these lines:

include_recipe "sidekiq"
include_recipe "redis-yml"
include_recipe "redis"

In your cookbooks/redis-yml/recipes/default.rb file, change the first line to also add redis.yml on utility instances:

if ['app_master', 'app', 'util'].include?(node[:instance_role])

Add this to your before_restart.rb deploy hook:

on_app_servers_and_utilities do
  # link redis.yml in current/config to shared/config
  run "ln -nfs #{config.shared_path}/config/redis.yml #{config.release_path}/config/redis.yml"
end

Then, create a file in your config/initializers directory called sidekiq.rb that looks like this (replacing “<yournamespace>” with whatever you want your redis namespace to be, mine is “<appname>:<environment>”). This was pretty much taken wholesale from Add Redis To Your Application.

# check if the redis.yml file exists - if you are running your staging env as 
# a solo instance without a redis utility instance, it won't
if File.exists?(Rails.root + 'config/redis.yml')
  # Load the redis.yml configuration file
  redis_config = YAML.load_file(Rails.root + 'config/redis.yml')[Rails.env]

  if redis_config
    Sidekiq.configure_server do |config|
      config.redis = {
         namespace: "<yournamespace>",
         url: "redis://#{redis_config['host']}:#{redis_config['port']}"
      }
    end
    Sidekiq.configure_client do |config|
      config.redis = {
         namespace: "<yournamespace>",
         url: "redis://#{redis_config['host']}:#{redis_config['port']}"
      }
    end
  end

else

  Sidekiq.configure_server do |config|
    config.redis = {namespace: "<yournamespace>"}
  end
  Sidekiq.configure_client do |config|
    config.redis = {namespace: "<yournamespace>"}
  end

end

Upload and apply your recipes and deploy your application.

Finally, check your log directory on your app instance to make sure you are connecting to the right instance. in /data//current/log/sidekiq_0.log it should say something like:

2013-08-30T23:11:25Z 22052 TID-17e8eg INFO: Booting Sidekiq 2.6.0 with Redis at redis://(some internal ip):6379/0

It should NOT say:

2013-08-30T10:27:50Z 25034 TID-17uk98 INFO: Booting Sidekiq 2.6.0 with Redis at redis://localhost:6379/0

You can check to make sure you are connecting to the right instance by checking your node info when you SSH into the app instance:

sudo gem install jazor
sudo jazor /etc/chef/dna.json

Look for a node like this:

  "utility_instances": [
    {
      "name": "redis",
      "hostname": "(some internal ip)"
    }

This hostname IP should match the one in your sidekiq log. Ta da!

Checking your SSL Certificate setup

Had a problem recently where the SSL cert expired and I didn’t add the intermediate certs when putting the new one in an EC2 instance. Made for some annoying troubleshooting.

This service will check your setup and make sure everything is correct:

http://www.digicert.com/help/

Ruby on Rails and FTPS

If you’re unlucky enough to have to connect to an FTPS server (SFTP ends up being much easier), the Double Bag FTPS gem makes things much easier.

A few finer points to note:

  • “verify_mode: OpenSSL::SSL::VERIFY_NONE” makes your life easier in development mode – not to mention some FTPS sites won’t even have one
  • Most servers don’t like active mode, so explicitly use passive mode. Your connection ends up hanging without it.

So usage is:

DoubleBagFTPS.open(host, user, password, nil, DoubleBagFTPS::EXPLICIT, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |ftps|
 ftps.passive = true
 ftps.put("myfile.txt", filename)
 end

Blog at WordPress.com.

Up ↑