James Johnson

RSS
May 8

Test

test

May 1

Ridiculously Easy File-Sharing: Let's Crate: Crate+

letscrate:

Over the past few months, our team has been judiciously testing a new, faster, speedier, and more cost-efficient backend for the infrastructure that powers Crate.

In the process of cleaning up the code behind our web application (both backend and frontend), we have made the entire site faster and…

Hooking Up My Rails App with Amazon s3 Using Paperclip

For quite some time I have been meaning to figure out how to get my static content onto Amazon s3. Using the heroku help here it wasn’t too bad at all! This is how I did it:

First go to Amazon’s AWS page here and sign up for s3. You then need to create a bucket, and it needs to be unique across the whole of Amazons site. As you can see, my bucket is called media.domainsby.me. It does not need to be reliant on a domain name, but I figured there would be a good shot it was unique.

Next I added the gems ‘paperclip’ and ‘aws-s3’ to my Gemfile and ran bundle install.

Then I modified my model to reflect the storage place for my application. If you notice, I am naming the image that I am uploading “background” and I am referencing a s3.yml file that has my credentials.


//This is my model 
class User < ActiveRecord::Base

has_attached_file :background,
                :storage => :s3,
                :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
                :path => "/:style/:filename"
end

After you add this to the model, you need to run a migration in order to tell you application information about the image. If you are using heroku, you still need to run this migration. I forgot this step at first and while I was able to save images - my application did not know the names of those files.


class AddBackgroundToUser < ActiveRecord::Migration
  def self.up
    add_column :users, :background_file_name, :string
    add_column :users, :background_content_type, :string 
    add_column :users, :background_file_size, :integer
  end

  def self.down
    remove_column :users, :background_file_name
    remove_column :users, :background_content_type
    remove_column :users, :background_file_size
  end
end
Then Run:

rake db:migrate
Now add the s3.yml file under config/s3.yml

//here is the s3.yml file

development:
  bucket: media.domainsby.me
  access_key_id: ACCESS_KEY
  secret_access_key: SECRET_ACCESS_KEY

test:
  bucket: media.domainsby.me
  access_key_id: ACCESS_KEY
  secret_access_key: SECRET_ACCESS_KEY

production:
  bucket: media.domainsby.me
  access_key_id: ACCESS_KEY
  secret_access_key: SECRET_ACCESS_KEY

Then finally, I put in the necessary information to both save and retrieve images - On my form I put this code for uploading images on the site:


<%= form_for @user, :html => { :multipart => true } do |f| %>
<%= f.file_field :background, :class => "inputshome" %>
<% end %>

And then in my show view in order to retrieve the image from Amazon


<%= image_tag @user.background.url %> 

Its that easy! If you are having trouble, jump into your console and make sure that the User model knows where the image is e.g. run User.last.background.url and see if it returns anything. In order to test if the image is being saved correctly, you can log into your amazon account and check if it is there.

Let me know if you have any questions!

Username as slug / domain URL in Rails 3

I am currently working on a rails app that has user profile pages, and I wanted to use those usernames as the domain slug. Meaning I want it to look like www.exampledomain.com/jamesjohnson. This was actually pretty easy to do and really just required a small modification to the config/routes.rb file.

In my user model, one of my columns is username and so that is what I used. For the profile page, I figured the show action would make the most sense as the controller/html file to use. Here is the code:


// config/routes.rb
resources :users
  match ":username" => 'users#show', :as => :username
Controller Code

def show
    @user = User.find_by_username(params[:username])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @user }
    end
  end

My First “Real” Rails App - Amazon Product API with JQuery Autocomplete UI

Today I finally finished the two month long saga of my most recent rails app. The app is called TheBookGnome (www.thebookgnome.com) and it is very simply a book voting website.

Users come to TheBookGnome.com - vote for books they like, add books they don’t see, and check out books posted by others. There is a little bit of a social aspect, with the concept of “karma” (haha this was a feature I added because I could), but for the most part its about the books.

The coolest part about building this, is that it covered some of the important stuff that goes into lots of web apps.
  1. Autocomplete (Used J-Query UI - Pasting my code below!)
  2. Authentication (Used Authlogic)
  3. Voting System (Vote_fu via the Thumbs_up gem)
  4. Basic intro to GIMP
  5. MUCH more comfortable with HTML and CSS.

In looking back on this project the biggest mistake was not having a plan. I was so excited to start building that I put no real effort into how I wanted the site to end up. This resulted in me wasting a TON of time and probably resulted in a worse finished product.

I think I am starting to learn why the “idea” is the least important part most of the time when it comes to small side projects like this… In order to include a bit of code, here are the main parts of my Autocomplete/Amazon API tie in. I used the JQuery Autocomplete UI and JSON format, if you have any questions let me know!

In my model I am making a call to the Amazon API and then returning the response in a JSON format. The JSON format is important for the autocomplete. JQuery has to be able to read the response you are sending, so formating the response like this, stops me from having to do it later in my controller or view.


// amazon.rb (model)
 def self.amazon(search)
     keywords = "#{search}"
     resp = Amazon::AWS.item_search('Books', { 'Title' => keywords })
     items = resp.item_search_response[0].items[0].item
        a = items[0]
        b = items[1]
        c = items[2]
        [{:label => "#{a.item_attributes.title.to_s[0,85] unless a.item_attributes.title.nil?}",
                     :value => "#{a.item_attributes.title.to_s unless a.item_attributes.title.nil?}",
                     :img => "#{a.small_image.url.to_s unless a.small_image.nil?}"""
                    },

        {:label => "#{b.item_attributes.title.to_s[0,85] unless b.item_attributes.title.nil?}",
                     :value => "#{b.item_attributes.title.to_s unless b.item_attributes.title.nil?}",
                     :img => "#{b.small_image.url.to_s unless b.small_image.nil?}"""
                    },
        {:label => "#{c.item_attributes.title.to_s[0,85] unless c.item_attributes.title.nil?}",
                     :value => "#{c.item_attributes.title.to_s unless c.item_attributes.title.nil?}",
                     :img => "#{c.small_image_url.to_s unless c.small_image.nil?}"""
                    }]

   end

My controller is pretty straight forward - it is calling the method that I defined in the model. The view is also pretty straight forward - just formatting to_json.html_safe. The last part is important and took me a while to figure out. The javascript was not being escaped correctly and this method fixed it up for me.


//amazon_controller.rb
    def index
        @amazon = Book.amazon(params[:term])

        respond_to do |format|
        format.html
        format.js
         end
  end

// index.js.erb

<%= @amazon.to_json.html_safe %>

Finally, my JS I ended up modifying an example on the JQuery UI documentation page. As you can see, I am appending both the image and the label to a list, which then with my css, I formatted to show correctly. Datatype here is JSON, as i mentioned earlier, and the url: amazon.js is what ends up getting returned to JQuery to format as autocomplete. If you visit the url /amazon.js - you should see your data being returned there in JSON format, if not, then the issue is not with the autocomplete code, but with the way you are accessing the data.

//javascript/application.js
$(document).ready(function(){
$(".auto_search_complete").autocomplete({
dataType: "json",
source: '/amazon.js',
minLength: 3
}).data( "autocomplete" )._renderItem = function(ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + "<img src='" + item.img +" '>" + item.label + "<a/>" )
.appendTo( ul );} })

Nothing special about the form, I did it in HAML because I was following along another example that did it that way, but I don’t think it ended up making a difference. As you can see, the :term gets passed to the query, which then ends up being what is used to search Amazon. The classes and ids are used by JQuery in order to execute the autocomplete code, and also by the CSS in order to modify the forms appearance.


// new.html.haml 
  - form_tag '/amazon/index', :method => 'get', :id => 'search_form', :class => 'search' do
     %p
        = text_field_tag :term, params[:term], :class => "auto_search_complete"
        = submit_tag "add books", :name => nil, :class => 'button', :id => "search_btn"

Let me know if you have any questions!

Do you know anything about PHP? If not, why did you choose ruby-on-rails over PHP?

I don’t know much about PHP, except that the frameworks do not seem as “popular”. I put that in quotes because I don’t really know, its just the perception that I get from reading about others experiences and advice from friends. I know that symfony is supposedly a pretty cool, but I have never used it.

My goals are very much focused on web applications, and ruby on rails seems to be one of the best tools for doing that quickly. Especially with Heroku, it means there is a whole lot less that you need to learn to get started.

I'm in EXACTLY the same position as you are with learning RoR. I'm the Art Director at Blind Acre Media and feel to better communicate with the dev team, I should be able to speak their language. Now, my question for you is, did you start by learning Ruby basics before you jumped into Rails? If so, when did you feel you learned enough Ruby to feel safe moving on to Rails?

Anonymous

I still don’t really know a whole lot of ruby and it is sometimes very limiting. I spent a little while reading through why’s poignant guide to ruby and then read through a couple of other online tutorials ( links below in other question), but for the most part I used the rails scaffold code to figure some of the basics out. While it doesn’t teach a lot of ruby, it is really helpful for learning the basics of rails and gives you enough ruby to do the basic stuff needed for simple webapps.

Like I said below, just jumping right into the rails tutorial on the homepage and then watching some screencasts is a pretty great way to go about starting.

Your link to YouRenew in the sidebar is not working. If you try http:// before what you have now, does it help?

woops!

Thanks for that. I didn’t realize it was broken.

Any books or other resources you could point me to for learning code? I have zero technical background, but want to learn/struggle. Thanks for the advice in advance.

See below!

Thanks!

James