How to setup twitter bootstrap from scratch with rails no gem

3 Comments

This is handy if you want to use twitter bootstrap, but don’t want to be dependent on updates from gems. With this you can update your bootstrap library’s whenever you want.

Create a new app

rails new foo

Create some scaffolding

rails g scaffold Post title:string description:text
rake db:migrate

Should have something that looks like this:

rails-app-scratch

Add the twitter bootstrap files from scratch

Download Bootstrap http://getbootstrap.com/

Copy
bootstrap/dist/css/bootstrap.css
bootstrap/dist/css/bootstrap.min.css

to: app/assets/stylesheets

Copy
bootstrap/dist/js/bootstrap.js
bootstrap/dist/js/bootstrap.min.js

to: app/assets/javascripts

Append to: app/assets/stylesheets/application.css
*= require bootstrap

adding-twitterbootstrap-cs

Append to: app/assets/javascripts/application.js
//= require bootstrap

adding-twitterbootstrap-js

App should now look like this:

app-wit-twitter-boostrap-files

Add the following twitter bootstrap code

app/view/layout/application.html.erb

<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
  <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">Project name</a>
    </div>
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Home</a></li>
        <li><a href="#about">About</a></li>
        <li><a href="#contact">Contact</a></li>
      </ul>
    </div><!--/.nav-collapse -->
  </div>
</div>
  
<div class='container-fluid'>
  <% flash.each do |key, value| %>
      <div class='alert alert-<%= key %>'><%= value %></div>
  <% end %>
  <div class='span12'><%= yield %></div>
  <%= debug(params) if Rails.env.development? %>
</div>
  
</body>

You can also add some copy copy like this:

app/views/permits/index.html.erb

<div class="container">
 
      <div class="starter-template">
        <h1>Bootstrap starter template</h1>
        <p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
      </div>
 
</div><!-- /.container -->

Should now look like this:

twitter-bootstrap-page-with-code

And you will know the javascript is working when you click on the x3 bars and they expand like this:

twitter-bootstrap-menu-expanded

But you can also see we have a problem. The top of our page is cut off by the menu. Fix that by creating a custom.css.scss file and putting the following code in there.

app/assets/stylesheets/custom.css.scss

body {
  padding-top: 50px; /* or 165px */
}
.starter-template {
  padding: 40px 15px;
  text-align: center;
}

twitter-bootstrap-fixing-spacing-at-the-top

Should now look like this:

rails-twitter-bootstrap-app-wrong-font

OK. Not bad. Could stop here if we want. But one thing to note is that the scaffold.css.scss font (this comes as part of the rails scaffolding) is overriding our default twitter bootstrap font (you can tell by going to the twitter website and seeing there text).

To fix that comment out or remove the text from scaffolds.css.scss

app/assets/stylesheets/scaffolds.css.scss

//body {
//  background-color: #fff;
//  color: #333;
//  font-family: verdana, arial, helvetica, sans-serif;
//  font-size: 13px;
//  line-height: 18px;
//}
//
//p, ol, ul, td {
//  font-family: verdana, arial, helvetica, sans-serif;
//  font-size: 13px;
//  line-height: 18px;
//}

Your app should then look something like this:

twitter-bootstrap-and-rails-from-scratch

Voila! You are done. Now you can update, or change twitter bootstrap to any version you like without having to wait for a gem to update.

Links that help:

http://stackoverflow.com/questions/18371318/installing-bootstrap-3-on-rails-app
http://getbootstrap.com/examples/starter-template/

Update

The gem way to use Twitter bootstrap is

gem 'bootstrap-sass',             '3.2.0.0'

And then convert scaffolding generated models by replacing

        format.html { redirect_to @permit, notice: 'Permit was successfully created.' }

With

      if @permit.save
        flash[:success] = 'Permit was successfully created.'
        format.html { redirect_to @permit }
        format.json { render :show, status: :created, location: @permit }
      else

      flash.now[:danger] = 'Invalid email/password combination'
      flash[:success] = &amp;amp;amp;quot;Welcome to the Construction Work Permit System!&amp;amp;amp;quot;

Replace scaffolding buttons

 &lt;%= f.submit %&gt;

with

    &lt;div class=&quot;form-actions&quot;&gt;
      &lt;%= f.submit nil, :class =&gt; 'btn btn-primary' %&gt;
    &lt;/div&gt;
Advertisement

How to create a new Rails Page

Leave a comment

Some notes to remind me of the generators and classes necessary for creating a new rails page.

Start with a new generator

> rails generate controller Sessions –no-test-framework

Add some routes

SampleApp::Application.routes.draw do
  resources :users
  resources :sessions, only: [:new, :create, :destroy]
  root  'static_pages#home'
  match '/signup',  to: 'users#new',            via: 'get'
  match '/signin',  to: 'sessions#new',         via: 'get'
  match '/signout', to: 'sessions#destroy',     via: 'delete'

end

Create the initial controller

class SessionsController < ApplicationController

  def new
  end

  def create
    render 'new'
  end

  def destroy
  end
end

Manually create a new page

app/views/sessions/new.html.erb

<% provide(:title, "Sign in") %>
<h1>Sign in</h1>

Links that help
http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#sec-sessions_controller

Rails has_many example

Leave a comment

Here are some notes on how to create a has_many relationship and the corresponding APIs for each entity.

> rails new hasMany
> rails g scaffold User name:string
> rails g scaffold Micropost content:string user_id:integer

user.rb

class User < ActiveRecord::Base
   has_many :microposts, dependent: :destroy
   end

micropost.rb

class Micropost < ActiveRecord::Base
  belongs_to :user
end

Sample calls

> micropost.user
> user.microposts
> user.microposts.create(arg)
> user.microposts.build
> @micropost = user.microposts.build(content: “Lorem ipsum”)

Links that help
http://ruby.railstutorial.org/book/ruby-on-rails-tutorial#sec-demo_user_has_many_microposts

How do rails environments work?

Leave a comment

Rails environments are wonderful. But they can be a bit confusing do to some inconsistency in terms of which environments are affected when you run certain rake tasks.

After some digging I think I figured it out.

db:create – affects both development and test environments
db:drop – only affected development (though this has changed)
db:migration – runs against your current environment (usually development)

hence the need for
db:test:prepare (to apply migrations against your test environment)

So in summary, you always need to specify the environment your rake tasks run against

$ rake foo RAILS_ENV=test

With the exception of db:create and db:drop above.

Links that helped:

https://github.com/rails/rails/pull/2419
http://railsforum.com/viewtopic.php?id=6648
http://jasonseifer.com/2010/04/06/rake-tutorial

How to setup Rails3 postgres on mac

9 Comments

Update

A much better way to install Postgres locally is to use Postgres.app.

Do this and use the following commands to create your local root user (with no password) and database instance.

psql template1 -h localhost
CREATE USER root;
CREATE DATABASE <your db name>;
GRANT ALL PRIVILEGES ON DATABASE <your db name> to root;
\q

=====================================

Wanting to align with Heroku I decided to setup a local instance of postgres.
It was more complicated than I would have liked, but here are some sketchy notes that might help if you need to go through the same thing.

Install postgres

$ brew install postgresql

After trying the EnterpriseDB one click deploy I found the homebrew install most stable.

Create Rails3 app with postgres as database

$ rails new pg -d postgres

Create new postgres database user

$ cd
$ sudo su postgres
Password:
$ createuser jr
$ Shall the new role be a superuser? (y/n) y
$ exit

if you get a getcwd: cannot access parent directories: Permission denied
just type ‘cd’ or ‘cd /’ and goto a directory where permissions aren’t an issue.

Create databases

$ sudo su postgres
Password:
$ psql template1
Password:

template1=# \l
template1=# CREATE DATABASE pg_development;
template1=# CREATE DATABASE pg_test;
template1=# \q

Login to terminal

$ psql -U postgres -d pg_development
Password:

config/database.yml

development:
adapter: postgresql
encoding: unicode
database: pg_development
pool: 5
username: postgres
password: root

test:
adapter: postgresql
encoding: unicode
database: pg_test
pool: 5
username: postgres
password: root

This was all setup and pre-populated. Only had to set username and password.

Test

$ rake db:create
$ rails generate scaffold Post name:string title:string content:text
$ rake db:migrate

Should be good to go. If you run into problems let me know and I will try to keep this up to do.

kill hanging postgres processes

Sometimes I have to manually kill postgres instances when I do a redeploy.
Pattern I follow is:
> db.sh (rebuild database)
> sudo kill -9
> manually restart server using pgadmin
> restart local rails server

— it’s a pain and I will update this when I find a better way

stackoverflow
postgres

Links that helped
http://www.funonrails.com/2011/03/getting-started-with-rails-3-postgres.html
http://www.mcbsys.com/techblog/2011/10/set-up-postgresql-for-rails-3-1/
http://devcenter.heroku.com/articles/local-postgresql#macintosh

How to embed HTML within a rails flash response

Leave a comment

It doesn’t look pretty, but if you really wanted to embed a link in your rails flash response you could do it like this:

      flash[:success] = "Foo. #{ActionController::Base.helpers.link_to "Create new listing", '/listings/new'}".html_safe

Couple other options can be found here:

http://stackoverflow.com/questions/4051423/using-html-in-rails-flash-messages

How to add a boolean column to a table in rails

Leave a comment

As a reminder to myself, here are some notes on how to add a boolean column to a table in rails3.

Step 1: Create migration

rails generate migration add_public_to_listings admin:boolean

Step 2: Write unit tests on model

listing_spec.rb

    describe "admin attribute" do

      before(:each) do
        @listing = @user.listings.create!(@attr)
      end

      it "should respond to public" do
        assert_respond_to(@listing, :public)
      end

      it "should not be public be default" do
        assert !@listing.public
      end

      it "should be converible" do
        @listing.toggle!(:public)
        assert @listing.public
      end
    end

Step 3: Update test data

populate.rake

def make_listings
  puts "----------------"
  puts "--- listings ---"
  puts "----------------"

  myUser = User.find_by_email("a@a.com")

  ls1 = myUser.listings.create!(:title => "The Mona Lisa",
                               :description => "Master peice",
                               :category_id => 2,
                               :address => "T3H0E2",
                               :location => "Calgary, Alberta, Canada")
  ls1.toggle!(:public) 

Note: We set the :public value through the toogle for security reasons. Only those variables exposed via attr_accessible

class Listing < ActiveRecord::Base
attr_accessible :title, :description, :category_id, :address, :location

can be set through mass assignment. This prevents bad guys from changing values like this:

put /listings/17?public=1

Thanks again Michael for the great example.

Rails TimeRange

1 Comment

Say you want to query your backend objects with a range of times.

One way to do that is to define a TimeRange object which captures the time ranges you are interested in:

TimeRange.rb

class TimeRange
  def self.today
    (Time.now.midnight)..Time.now.end_of_day
  end

  def self.yesterday
    (Time.now.midnight - 1.day)..Time.now.end_of_day
  end

  def self.last_week
    (Time.now.prev_week)..Time.now.end_of_day
  end

  def self.ages_ago
    (Time.now.prev_year)..Time.now.end_of_day
  end
end

And then using these to define your ‘created_at’ parameter:

SomeController.rb

    case params[:date_posted]
    when 'today'
      created_at = TimeRange.today
    when 'yesterday'
      created_at = (Time.now.midnight - 1.day)..Time.now.end_of_day
    when 'last week'
      created_at = (Time.now.prev_week)..Time.now.end_of_day
    when 'ages ago'
      created_at = (Time.now.prev_year)..Time.now.end_of_day
    else
      logger.error "Unknown posted date on listings search #{params[:date_posted]}"
    end

which can then be used in your search:

    @attr = {
            :location => @location,
            :category_id => params[:category_id],
            :created_at => created_at
    }

    @listings = Listing.where(@attr)

Not bad!

See my previous post here for where to place your TimeRange object and how to reference it from another ruby class.

How to reference domain classes in rails

1 Comment

Working with active records in rails is nice because a lot of your domain is directly represented in your model classes.

Sometimes however, you still need to create some domain classes that aren’t tied to a database model, and reference them in your app.

I’m not sure what the best way (or convention) is for doing this, but what’s been working for me is to create a separate directory called domain

and place my domain object(s) in there:

class TimeRange
  def self.today
    (Time.now.midnight)..Time.now.end_of_day
  end

  def self.yesterday
    (Time.now.midnight - 1.day)..Time.now.end_of_day
  end

  def self.last_week
    (Time.now.prev_week)..Time.now.end_of_day
  end

  def self.ages_ago
    (Time.now.prev_year)..Time.now.end_of_day
  end
end

And then referencing them where I need them using the ‘require_relative’ command.

require_relative '../domain/time_range'
require_relative '../domain/constants'

class CitiesController < ApplicationController

How to drop, create, populate, and reset your rails database

Leave a comment

Getting frustrated with all the commands I needed to type I created the following scripts and tools to simplify destroying and recreating my rails database.

Step 1: Create an ‘all’ task.

lib/tasks/db.rake

namespace :db do

  task :all => [:environment, :drop, :create, :migrate, :populate] do
  end

end

The basic commands for recreating and populating your database from the command line often require some variation of:

Rebuild db
$ rake db:drop
$ rake db:create
$ rake db:migrate
$ rake db:fixtures:load RAILS_ENV=test
$ rake db:test:prepare

This rake task does most of this for us. To get data into the database I create a second task shown above ‘populate’.

Step 2: Create a populate task.


require 'faker'

namespace :db do

  desc "Fill database with sample data"
  task :populate => :environment do

    puts "----------------"
    puts "RAILS_ENV is #{RAILS_ENV}"
    puts "----------------"

    puts "----------------"
    puts "--- populate ---"
    puts "----------------"

    make_cities
    make_users
    make_categories
    make_listings
  end

end

def make_cities

  puts "----------------"
  puts "--- cities   ---"
  puts "----------------"

  City.create!(:name => "Calgary")
  City.create!(:name => "San Francisco")
end

def make_users

  puts "----------------"
  puts "---- users  ----"
  puts "----------------"


  admin = User.create!(:name => "aaa",
                       :email => "aaa@aaa.com",
                       :password => "foobar",
                       :city_id => 1)
  admin.toggle!(:admin)
  2.times do |n|
    name = Faker::Name.name
    email = "example-#{n+1}@railstutorial.org"
    password = "password"
    User.create!(:name => name,
                 :email => email,
                 :password => password,
                 :city_id => 1)
  end
end

This task uses the fake gem to create and load test data into which ever environment we pass in via ‘RAILS_ENV’. It won’t work by itself yet, but we can now run this using our ‘all’ task by going:

> rake db.all
> rake db.all RAILS_ENV=test

Step 3: Put it together in a bash script

db.sh

#!/bin/bash
echo "Reseting database"
rake db:all
rake db:all RAILS_ENV=test

Now when ever I would to scrap and start all over, I rollback my git repository, and rebuild my db.

Voila. Clean slate and I can what ever it was I was trying to do again.

Older Entries

%d bloggers like this: