KISS: Slurping up File Attachments
I’ve been heavily involved in an ecommerce project running on Rails 3, using Piggybak, RailsAdmin, Paperclip for file attachment management, nginx and unicorn. One thing that we’ve struggled with is handling large file uploads both in the RailsAdmin import process as well as from the standard RailsAdmin edit page. Nginx is configured to limit request size and duration, which is a problem for some of the large files that are uploaded, which are large purchasable, downloadable files.
To allow these uploads, I brainstormed how to decouple the file upload from the import and update process. Phunk recently worked on integration of Resque, a popular Rails queueing tool which worked nicely. However, I ultimately decided that I wanted to go down a simpler route. The implementation is described below.
Upload Status
First, I created an UploadStatus model, to track the status of any file uploads. With RailsAdmin, there’s an automagic CRUD interface connected to this model. Here’s what the migration looked like:
class CreateUploadStatuses < ActiveRecord::Migration
def change
create_table :upload_statuses do |t|
t.string :filename, :nil => false
t.boolean :success, :nil …
rails
Simple Example of Dependency Injection with Rails
Today I came across a great opportunity to illustrate dependency injection in a simple context. I had a Rails partial that was duplicated across two subclasses. The partial was responsible for displaying options to create a new record from the data of the current record. It also offered two types of copy, shallow and deep. The shallow copy used a button to POST data, while the deep copy offered a form with some additional options. The only difference between the partials was the path to post data to. Let’s see this in code.
#app/views/fun_event/_copy_options.html.erb
button_to(t("create_and_edit_shallow_copy"), fun_event_path(:from_event => @event.id, :return => true), : id => "shallow_copy_btn")
form_tag(fun_event_path(:return => true)) do
#form code
end
#app/views/boring_event/_copy_options.html.erb
button_to(t("create_and_edit_shallow_copy"), boring_event_path(:from_event => @event.id, :return => true), : id => "shallow_copy_btn")
form_tag(boring_event_path(:return => true)) do
#form code
end
The first, failed iteration
To remove the duplication, I passed in a path option into the partial, replacing specific …
rails
.rbenv and Passenger: Working through an Upgrade
Yesterday, I worked on upgrading the Piggybak demo application, which runs on Piggybak, an open source Ruby on Rails ecommerce plugin developed and maintained by End Point. The demo was running on Ruby 1.8.7 and Rails 3.1.3, but I wanted to update it to Ruby 1.9.* and Rails 3.2.6 to take advantage of improved performance in Ruby and the recent Rails security updates. I also wanted to update the Piggybak version, since there have been several recent bug fixes and commits.
One of the constraints with the upgrade was that I wanted to upgrade via .rbenv, because End Point has been happily using .rbenv recently. Below are the steps Richard and I went through for the upgrade, as well as a minor Passenger issue.
Step 1: .rbenv Installation
First, I followed the instructions here to install rbenv and Ruby 1.9.3 locally under the user that Piggybak runs under (let’s call it the steph user). I set the local Ruby version to my local install. I also installed bundler using the local Ruby version.
Step 2: bundle update
Next, I blew away the existing bundle config for my application, as well as the installed bundler gem files for the application. I followed the standard steps to install and …
hosting piggybak rails
Speeding Up Integration Tests with PostgreSQL
Many people tend to say they don’t want to write tests. One of the reasons is usually that the tests are too slow. The tests can be slow because they are written in a bad way. They can also be slow because of slow components. One such component is usually a database.
The great thing about PostgreSQL is that all types of queries are transactional. It simply means that you can start a transaction, then run the test, which can add, delete and update all the data and database structure it wants. At the end of the integration test, there should be called rollback which just reverts all the changes. It means the next test will always have the same database structure and data before running, and you don’t need to manually clear anything.
For running the integration tests we need a test database. One of the most important things when running test is speed. Tests should be fast, programmers don’t like to wait ages just to know that there is something wrong.
We can also have a read only databases for the tests. Then you don’t need to worry about the transactions, however you always need to ensure the tests won’t change anything. Even if you assume your tests won’t make any changes, it is …
performance postgres testing
Moving a Commit to Another Branch in Git
Perhaps you’ve made the same mistake I have. You’re right in the middle of developing a feature when a request comes up to fix a different completely unrelated problem. So, you jump right in and fix the issue and then you realize you forgot to start a new git feature branch. Suddenly you realize that you need to merge just the fix you made, but don’t want to merge the commits from the previous feature your working on.
Git rocks at manipulating branches and I knew this, but I wasn’t sure how to just move one commit to the master branch. After some digging and a little trial and error, I finally figured it out. This may not be the simplest approach, but it worked for me and wanted to share.
The branches I’ll be working with are master and feature. In the current scenario, the feature branch is 4 commits ahead of the master and the branch that I want to bring over is just the most recent.
First things first, I need to ensure my master branch is up to date.
git checkout master
git pull origin master
Then I’ll checkout my feature branch and make sure it’s completely up to date with the master branch.
git checkout feature
git rebase origin/master
Next, I’ll create a temporary feature …
git
Guard Cucumber Command Prefix
Guard is an incredibly useful ruby gem that allows you to monitor changes to files and then execute commands when files change. Some of the common uses of guard are to watch code changes and then automatically execute your test suite. Guard comes with a plugin framework that allows developers to write specific watches. Some common plugins are guard-rspec and guard-cucumber. You can see a list of over 120 plugins on the rubygems website.
Yesterday I was working on some cucumber tests and wanted to use guard to automatically run my tests. I currently run all of my cucumber tests using capybara-webkit to allow me to run my tests in the terminal. To do so, I need to run xvfb-run bundle exec cucumber. The xvfb-run command allows the test to run in a headless X11 window. The problem is that the guard-cucumber plugin didn’t allow for a command prefix so my tests wouldn’t run correctly.
Thankfully, the guard-cucumber plugin is available on github and I was able to fork the project and add an option to allow a prefix. When it was completed, I added some documentation and a test and then made sure the tests all passed. I thought others may want this functionality as well so I sent a pull …
ruby
Company Meeting Wrap-Up
End Pointers at our annual company meeting!
Many of us End Pointers are back to work after last week’s annual company meeting of 2012 held in New York City. We attended a 3-day conference full of technical tips, client updates, and general company news. Everyone participated in live blogging during the conference, producing valuable documentation to allow us to revisit what was discussed. Here’s a list of all the articles in case you missed any, or felt overwhelmed by the articles in the RSS feed:
company conference
Developing a Spree Application
Mike Farmer presented one of the projects he worked on. He gave us a very detailed overview of integration of a Spree application into Facebook for a large client.
He also described the changes that were made in the Spree project to customize it to the client’s needs.
The most interesting thing in this Spree shop usage is that the company’s clients make extensive use of the admin panel and they can sell their own products for other clients.
Mike showed us a great overview of writing better Rails applications using better object oriented code along with TDD and extensive SASS usage. He also described the great tools he uses including Screen and Vagrant.
Mike also talked about the things he learned during working on this project, especially about Spree and Ruby.
conference ecommerce rails social-networks spree