Scripting

Ramblings and links to interesting snippets


Simple reference for creating a Rails migration

I keep forgetting the rails generator syntax for migrations :X  I can never find just a quick easy guide for it – so I thought I’d write one up!

Instructions

  1. cd …
    obviously first make sure your in the main project folder in the console
  2. export RAILS_ENV=environment
    Also, make sure you’re in the right environment, you will probably want to make the change first in your test or development environment and then put it to production
  3. rails g migration AddColumnToModel column_name:column_type
    Here’s the main part, on  older versions rails g migration will be script/generate migration.  The “AddColumnToModel” syntax is important and should relate to the migration you’re making like “AddEmailToUser” and then at the end you can add a “column_name:column_type” reference for each column you want to add, for instance with the last example you would put “email:string
  4. rake db:migrate
    run the migration and add those columns to the database!  You’ll probably want to review the migration that was generated first though – it’ll be the latest file in the …/db/migrate directory

AND MAKE SURE TO RESTART YOUR SERVER AFTER MAKING A CHANGE

Column Types

  • binary: for files/ data blob
  • boolean: true/false
  • date: only date: (year, month, day)
  • datetime: date + time
  • decimal: precise decimal numbers – for when math neds to be accurate
  • float: decimal numbers
  • integer: whole numbers
  • string: 255 max alphanumeric characters
  • text: unlimited alphanumeric characters
  • time: only time (hours, minutes, seconds)
  • timestamp: same as datetime

 

And, if you make a mistake a quick way to go back and fix it is “rake db:migrate:redo” that will undo your last change, and re-run it.

Also, if you want to only run “rake db:migrate:up VERSION=20090408054532”

In a pinch you can also run a migration by hand in the console with the following format:
ActiveRecord::Migration.add_column :table, :column_name, :column_type

References:
http://stackoverflow.com/questions/11889048/is-there-documentation-for-the-rails-column-types
http://stackoverflow.com/questions/15162055/rails-generate-migration
http://stackoverflow.com/questions/7694487/ruby-on-rails-how-can-i-revert-a-migration-with-rake-dbmigrate

Permalink » No comments

Social Login with Phonegap, Omniauth, Tokens, and InAppBrowser

For a project I needed to integrate Facebook and Twitter logins to a phonegap app.  I went through a ton of plugins and jsOAuths, but they were all quite cumbersome. I really wanted a simpler approach that would handle Twitter and Facebook at the same time.

This article about Twitter integration with Child Browser got me started in the right direction.  It’s a little dated with Child Browser, so I set out to update it to work with InAppBrowser, but during the process I realized that I could actually handle this issue a lot simpler.  Mostly because I only needed to login and didn’t require any deeper integration with Social platforms.

So after a little more digging I came across this lovely article on cross window communication with InAppBrowser which was everything I needed to take care of business!

In my case, the server is going to be doing all the heavy lifting, and for this project we already had Omniauth set-up for social login and tokens so I only needed to make a few tweaks to get this rolling.

The first tweak was to get it to output JSON for the App.  Out of the box Omniauth will keep track of your params, so I made it return a JSON response when I requested it in the query string like so “/users/auth/facebook?json=true”

Just for example, here how it would look if you were using the standard facebook action for omniauth:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def facebook
    @user = User.from_omniauth(request.env["omniauth.auth"])
 
    if @user.persisted?
      sign_in @user, :event => :authentication #this will throw if @user is not activated
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      return redirect_to new_user_registration_url
    end
 
    return render :json => current_user if request.env["omniauth.params"]["json"]
 
    set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    redirect_to "/"
  end
end

The important parts here are:

  • I’m using “sign_in” instead of “sign_in_and_redirect” so I can handle the redirection later down the line.
  • Then I’m adding in “return render :json => current_user if request.env[“omniauth.params”][“json”]” so the callback will output the current user in JSON.

In my case the JSON output for current_user includes a token I can use to integrate with the API.

With that all set you’re ready to capture that JSON in phonegap:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
win = window.open(base_url+'/users/auth/facebook?json=true', '_blank', 'location=yes,enableViewPortScale=yes');
win.addEventListener('loadstop', function (e) {
  if (e.url.indexOf(base_url) >= 0 && e.url.indexOf('callback') >= 0) {
    win.executeScript(
      { code: "document.body.innerHTML" },
      function(values) {
        r = values[0];
        r = r.replace(r.substring(0, r.indexOf('{')),"").replace(r.substring(r.indexOf('}'),r.length).replace(/}/g,''),"");
        r = jQuery.parseJSON(r);
        //now r.api_token is available to use however you need in your app
        win.close();
      }
    );
  }
});

This works by:

  1. First opening a window with the social login page “/users/auth/facebook?json=true
    on my app base_url is the domain of the API, like http://api.google.com for example.
  2. Next I’m listening for every-time the page in InAppBrowser finishes loading with “addEventListener(‘loadstop‘”
  3. Then I’m waiting for the URL to have my API’s domain name plus “callback” here “if (e.url.indexOf(base_url) >= 0 && e.url.indexOf(‘callback’) >= 0) {
  4. Once there I use “executeScript” to fetch the document body, which is returned as values[0].
  5. Then I clean the return value of any HTML using replace and substring, then parse that to JSON

After that you can use that token in your App however you need to integrate with your API.

Permalink » No comments

Clockwork for Laravel

unnamed

While watching some tutorials on laracasts I came across a pretty nifty tool for Laravel called Clockwork.  Clockwork includes a Google chrome extension and a back-end library on Github.  After configuring both you’ll have a clockwork tab in your inspector in Chrome.  You can use it’s functions to check how long code snippets take to execute, and echo out variables to the inspector just like console.log() in Javascript.  Neat! 🙂

Permalink » No comments

WordPress – Custom length excerpt

If you ever need a custom length excerpt in your wordpress site, and want to leave the excerpt length alone for the rest of the site, you can use wp_trim_words on the content to pull out exactly how many words you want the excerpt to be.

In the following example I made a 10 words excerpt, but you can make it any length you want by changing the number.

<?php echo wp_trim_words(get_the_content(), 10); ?>

Permalink » No comments

Strip links in HTML using Dreamweaver

I was putting together some “preview” HTML pages and needed to make sure the links didn’t go anywhere odd.  So I found out how to quickly strip out all the links from an HTML document using Dreamweaver’s regular expressions and find and replace.

It’s pretty easy, just put this in the find field:

<a href='(.*)’>

and this in the replace:

<a href=’#’>

And make sure to select “Use regular expression,” just like this:

strip_links

Permalink » No comments