Serving a file from your Rails app from another server protected by basic authentication

Interesting problem: Retrieve a document from one web service protected by basic auth (or some authentication mechanism) and serve it via a public link on another website.

It ended up boiling down to this code in the controller (reduced to be in the same method instead of factored out as it was.)

  def get_download
    response = Net::HTTP.start('localhost', '3010', {} ) do |http|
      request = Net::HTTP::Get.new('http://localhost:3010/my_document.pdf')
      request.basic_auth 'username', 's3cretpassword'
      http.request(request) do |response|
        send_data(response.body, filename: 'set_filename.pdf')
      end
    end
  end

has_one, reject_if, and accept_nested_attributes still fails validation

Problem

What I wanted to accomplish in my form was allowing an Account to manage a Devise user account.

Parent model code:

class Account
  has_one :service_user
 
  accepts_nested_attributes_for :web_service_user, :allow_destroy => true, :reject_if => :password_not_specified, :update_only => true
 
  def password_not_specified(attributes)
    attributes[:password].blank?
  end
end
Child model code:
 
class ServiceUser
  devise :database_authenticatable
 
  belongs_to :account
 
  validates_uniqueness_of :username
  validates_presence_of :password, if: Proc.new{|su| !username.blank? }
end

Controller code:

def update
  respond_to do |format|
    if @licensee.update(account_params)
  #etc...
end
 
private
def account_params
  params.require(:account).permit(:name, :address1, :address2, :city, :state_code, :zip, :website_url, :service_user_attributes => [:id, :username, :password, :_destroy])
end

Solution:

Password, unfortunately, doesn't exist in the Devise model, but it does exist when setting the password, so I validate the length instead if the password is not nil.

class ServiceUser
  devise :database_authenticatable
 
  belongs_to :account
 
  validates_uniqueness_of :username
  validates_length_of :password, :minimum => 14, if: Proc.new { |u| !u.password.nil? }
end

Unable to find any JVMs matching version "1.7" and Mac OS X Mavericks can't see JAVA_HOME

Background:

My .zlogin had a call to /usr/libexec/java_home 1.7 to set the JAVA_HOME to that of my Java 1.7 install, but it was an artifact of my former Mac OS X Lion configuration.

I finally decided to "fix" the problem by installing JRE 7, but found my JAVA_HOME to be /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java, and then found out that I needed to install the SDK to "fix" java_home. I made the mistake of attempting to install the Java Platform, Enterprise Edition 7 SDK (with JDK 7u45) bundle for Mac, which is a shell script. I first pointed it to the JRE 7 home, but found that that didn't have jar in the bin directory.

I found someone else with the same problem and someone else commenting not having to use a shell script to install on Mac. It got me thinking about splitting up the installs into JDK install and EE install.

Solution:

Try installing the Java Development Kit first and then running the unbundled EE SDK as follows:

The second download is a shell script, but it works fine after JDK install (especially compared to the bundled version).

.zlogin (or .zshrc) parse error near `\n'

This code was at the end of my .zlogin on my mac and was causing .zlogin:152: parse error near `\n'. The problem is rather bone-headed, but I went through trying to :set ff=unix, :set ff=mac in vim to try and remedy bad line endings.

function notify_preexec() {
  # Note the date when the command started, in unix time.
  CMD_START_DATE=$(date +%s)
  # Store the command that we're running.
  CMD_NAME="$1"
}
 
function notify_precmd() {
  # Proceed only if we've run a command in the current shell.
  # Proceed only if we've run a command in the current shell.
 
function notify_precmd() {
  # Proceed only if we've run a command in the current shell.
  if ! [[ -z $CMD_START_DATE ]]; then
    # Note current date in unix time
    CMD_END_DATE=$(date +%s)
    # Store the difference between the last command start date vs. current date.
    CMD_ELAPSED_TIME=$(($CMD_END_DATE - $CMD_START_DATE))
    # Store an arbitrary threshold, in seconds.
    CMD_NOTIFY_THRESHOLD=240
 
    if [[ $CMD_ELAPSED_TIME -gt $CMD_NOTIFY_THRESHOLD ]]; then
      # Beep or visual bell if the elapsed time (in seconds) is greater than threshold
      # Send a notification
      if [[ "$CMD_NAME" =~ 'rake' ]]; then
        say "$CMD_NAME FINISHED IN $CMD_ELAPSED_TIME SECONDS"
      fi
      unset CMD_NAME
      unset CMD_START_DATE
    fi
  fi
}

See it yet?

function notify_precmd() {
  # Proceed only if we've run a command in the current shell.
  # Proceed only if we've run a command in the current shell.
 
function notify_precmd() {

I somehow opened up the notify_precmd() function twice. I was mostly focusing on a missing fi and mismatched parens/braces.

Moving back to the last cursor position in line in vim

Ever have a stray keystroke in vim that jumped to somewhere you didn't intend to go?

Two backticks `` will jump to the exact position of where you were.
Two single quotes '' will jump to the first non-blank character where you were.

This also works for moving to the beginning of a line/cursor position set by a mark (

m{a-zA-z}

)

More explanation can be found at :help mark-motions.

Moving Static Files to the Assets Pipeline (upgrading from 3.0 to 3.1+)

For those who have done the upgrade, this is probably second nature: Recently stumbled upon static files in the public/javascripts directory and wanted to get them moved to the $RAILS_ROOT/app/assets/ directory.

This RailsCast, 282 Upgrading to Rails 3.1 provides most of the notes you need on doing this.

The first key is to include:

config.assets.enabled = true

Now, all those public folders:

public/javascripts
public/stylesheets
public/images

...need to be moved to:

app/assets/javascripts
app/assets/stylesheets
app/assets/images

Also... whenever the assets get served, the directory name under assets is removed, so that app/assets/myspecialfiles/stuff.png becomes http://example.com/assets/stuff.png

The latest info on the asset pipeline at

Enums in ActiveRecord 4.1 and options_for_select

Update: This StackOverflow answer provides a better way to use a drop-down with enums. I could've sworn I tried that, but maybe not.

I discovered something interesting about the way ActiveRecord 4.1 enums work. If you're trying to use them with options_for_select, you may need to do some little acrobatics with your enums.

Assume your model provides:

class Car < ActiveRecord::Base
  # body_style is an integer in the database
  enum body_style: [:coupe, :convertible, :van, :suv, :sedan]
end

And your update route for cars_controller does this:

class CarsController < ApplicationController
  before_action :set_car, only: [:show, :edit, :update, :destroy]
 
  # PATCH/PUT /cars/1
  # PATCH/PUT /cars/1.json
  def update
    respond_to do |format|
      if @car.update(car_params)
        format.html { redirect_to @car, notice: 'Car was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @car.errors, status: :unprocessable_entity }
      end
    end
  end
  private
    # Use callbacks to share common setup or constraints between actions.
    def set_car
      @car = Car.find(params[:id])
    end
 
    # Never trust parameters from the scary internet, only allow the white list through.
    def car_params
      params.require(:car).permit(:body_style)
    end
end

Then, using the enumeration in a form_for block in your view requires a deviation from what Car.body_styles will give you.

The value submitted by this form snippet won't validate because update is expecting the "string" key, and not the underlying numerical value of the table.

<%= form_for(@car) do |f| %>
  <%= f.label :body_style %>
  <%= f.select :body_style, options_for_select(Car.body_styles) %>

Instead, a little bit of transformation needs to be done so that the description/value pair for the elements are both the text value of the enum.

<%= form_for(@car) do |f| %>
  <%= f.label :body_style %>
  <%= f.select :body_style, options_for_select(Car.body_styles.map {|k,v| [k,v]}) %>

Or, with the selected value included:

<%= form_for(@car) do |f| %>
  <%= f.label :body_style %>
  <%= f.select :body_style, options_for_select(Car.body_styles.map {|k,v| [k,v]}, @car.body_style) %>

Nesting resource routes with alternate scopes and keys + strong parameters.

DISCLAIMER:
This is a contrived example translated from a case where it actually made way more sense to break the familiar nested resource pattern. Also, I haven't double-checked how Rails' pluralization rules would affect the naming of any given Species.

Say you have a pair of models:

class Species
  # id
  # latin_name_with_underscores
end
 
class Animal
  # name
  # species_id
end

Normally, you'd nest resource routes in your routes.rb file something like:

resources :species do
  resources :animal
end

And your routes would look something like:

/species/:species_id/animals
/species/:species_id/animals/:animal_id

But... what if you wanted different nesting, resource ids, and route names?

namespace :latin_species do
  scope '/:latin_name' do
    resources :animals
  end
end

Now you have:

/latin_species/:latin_name/animals
/latin_species/:latin_name/animals/:id

In your controller app/latin_species/animals_controller.rb, you can now do the following to set the appropriate parent and child:

class LatinSpecies::AnimalsController < ApplicationController
  before_action :set_species_and_animal
#
#
#
  def set_species_and_animal
    @species = Species.find_by(latin_name_with_underscores: params[:latin_name])
    @animal = Animal.find(params[:id]) if pararms[:id]
  end
end

Git wrapper for vim: fugitive.vim

Today's browsing through "plugins that I haven't made good enough use of" brings me to vim-fugitive:

:Gstatus pulls git status output into a vim split window. Pressing - on the line that a file is listed on either adds or removes a file from staging, and :Gcommit commits it.

:Gdiff opens a vertical split next to a file and uses vim's diff facility to compare working copy to staged version.

:Gblame opens a vertical split next to a file with an interactive git blame output that tracks the source file as you scroll. Pressing on a line opens the commit that changed the code (or o to open in a split.)

:Glog opens the log in the quickfix window:

  • :copen to open the quickfix window to scroll through the versions
  • :ccl close the quickfix window
  • :cn go to the next error in the quickfix window (append a number to jump # steps)
  • :cp go to the previous error in the quickfix window (append a number to jump # steps)

:Gmove performs a git mv and modifies the buffer location as well.
:Gremove performs a git rm and removes the buffer as well.

Other commands of interest that I haven't considered for my current workflow:
:Ggrep
:Gbrowse
:Git performs any other git command not already covered.
:Gedit, :Gsplit, :Gvsplit, :Gtabedit appear to open a repository object directly... not quite ready to pick at individual objects on that level.

Using vim-rails to help navigate the rails project.

In the interest of being able to quickly navigate my Rails projects, I decided to dive a little deeper into the vim-rails plugin.

This helpfile describes the commands in detail, but some of the quick commands are :Econtroller, :Emodel, :Eview, which pretty reliably jump between corresponding controller, model, and view.

:Espec needs a little more help, in that you have to specify the underlying model/view/controller under test to find the correct spec file. Jumping back to the corresponding file under test is a little more reliable.

If you want to go to the new file in a split, vsplit, or new tab, you can use substitute S/V/T for E (e.g., :Sspec, :Vmodel).

This plugin may seem a bit like overkill if you already have the CtrlP working the way you want it to, but I find that I like having the more focused search functionality of a per-model/controller search and the automatic jumping from model to controller in many instances where the model and controller directories have a lot of similarly named files.