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

Advertisements

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.

Older Entries

%d bloggers like this: