Transfer Ruby on Rails app, and mysql to sqlite

December 14, 2009

I just finished transferring a Ruby on Rails web site from one server to another and also transferring the data from MYSQL to sqlite. I solved all the problems with some help from Pat, and learned along the way.

The first problem was with my deployment using capistrano. Setting up the git repository, pushing it up–that was easy. For some reason my deployments were not working. Git pushes and pulls worked, and I could log into the server via ssh just fine. And when I did log in via ssh, I had to type my password. So I figured that my ssh public/private keys were not uploaded to the server. So I asked my server admin to update my ssh keys, and I emailed him the contents of my .ssh dir so he could dump them in my remote home dir.

This still did not resolve the problem.

Here is what my cap deploy would result in:

[76.73.15.5] executing command
** [76.73.15.5 :: err] Permission denied, please try again.
** [76.73.15.5 :: err] Permission denied, please try again.
** [76.73.15.5 :: err] Permission denied (publickey,password).
** fatal: The remote end hung up unexpectedly
command finished
*** [deploy:update_code] rolling back
* executing “rm -rf /home/andrew/apps/kpmstaffing/releases/20091207060339; true”
servers: ["76.73.15.5"]
[76.73.15.5] executing command
command finished
failed: “sh -c ‘git clone -q ssh://andrew@76.73.15.5/home/andrew/git/kpmstaffing /home/andrew/apps/kpmstaffing/releases

so after a while of fumbling around on my part, and expert looking and inspecting from my server admin, it was found that the problem was with my .ssh/* contents, something was wrong with those files and it was preventing my capistrano to deploy properly via ssh. So, the solution was some expert use of ssh-copy-id on the remote server. Or you could just resend your .ssh public/private keys somehow if you have this problem.

So now my cap deploy would work. The next step was to transfer the database from the live Web site to the new location.

This proved to be quite a task, even though I have done this before and I thought it was going to be easy. Well, there turned out to be some variables that I did not encounter before.

First rudiment, you have to have this file: backup.rake. I dont know where to get it from, I just had it from a project I worked on with a friend.

First thing I did was get a copy of the yml file that was automatically being made daily and sent to an email account that I have set up. I copied this file to my local computer.

Now, I also, just for fun, ran this command on the live web site:
rake db:backup:write

that created another yml file in db/backup/ on the remote server.

So now I had the auto backup yml file, and I could also make a backup yml file of the database any time I wanted. Now what?

Well, I was transferring from mysql to sqlite. So mysql wasnt a problem area because when I did the db:backup:write it just dumped all the data to a yml file in db/backup/. No problem. But on the new location of my web app, it is a bit different because you have to set up a shared db for sqlite. So first thing you have to do is alter your database.yml file to look like this in production:

production:
adapter: sqlite3
database: /home/andrew/apps/kpmstaffing/shared/db/production.sqlite3
pool: 5
timeout: 5000

Then, you have to do a cap deploy:migrate from the local computer, that puts some version of the database there, just something but its not your end product. BUT it should be the correct schema, just the data is not up to date.

Then you have to load the data in there, so get your latest backup yml file, and dump it into db/backup/ on the remote server into the correct version of the app. If you are using git then you will know what I’m talking about here.

now run these commands on the remote server:

rake db:migrate:reset RAILS_ENV=’production’
rake db:restore RAILS_ENV=’production’

That should put the data into the new shared db location. The db:restore command uses the latest file in db/backup/ and dumps data into the database.

Now, if you want to test it, run this on remote server:

./script/server -p 3001 -e production

Use whatever port you want to use, but definitely use ‘-e production’ or your test run will use the development database.

Now for some reason, I had some instructions from before to run this command to load the data into the tables:

rake db:backup:read RAILS_ENV=’production’

That ALWAYS failed and gave me this error:

rake aborted!
Don’t know how to build task ‘db:backup:read’

And I was stuck on this for a while. Finally I opened up backup.rake in lib/tasks/ to see how this file worked, and I noticed that there was no backup:read command, just “restore”. So I changed it to db:restore RAILS_ENV=’production’ and it worked.

So now my website is running. Thanks Pat for the help.


show a database record by word instead of an id number, ruby on rails guide

August 7, 2009

These instructions are to show you how to use a word in the url instead of an ID.

Like having a url that looks like this:

http://www.comickeith.com/biographies/keith

instead of

http://www.comickeith.com/biographies/1

This is much better for Search Engine Optimization, friendly urls for the public, easy to remember, and just looks better.

These instructions assume that you don’t have a “shortname” field in your table yet.

1 in your command line interface, inside the project directory, run this:

script/generate migration add_shortname

2 open the file db/migrate/LATESTTIMSTAMP_add_shortname.rb

This is the code that should be inside the class:

def self.up

add_column “pages”, “shortname”, :string

end

def self.down

remove_column “pages”, “shortname”

end

The “up” is run when you migrate, the “down” is run if you rollback

2b Run this at your command line:

rake db:migrate

3 open app/views/admin/Pages/_form.html.erb

Add this into the form:

<tr><td><p><label>Short Name:&nbsp;</label></td><td><%= f.text_field :shortname %></p></td></tr>

3 open the Page model in app/models/page.rb

Add these two lines:

validates_presence_of :shortname
validates_uniqueness_of :shortname

3b now go into your website into the admin section and put shortnames in all your records, you have to or you’ll get errors if you go on.

If you don’t have your web forms done for your adminstrative area, better go do that now, because you won’t be able to finish this target. or you can put data in the database using another way. but I suggest getting the admin forms done now. it will save you time in the long run.
See Create administrative area in ruby on rails

4 open app/controllers/pages_controller.rb, and add the following code:

#this line goes outside the defs, at the top of the class
rescue_from ActiveRecord::RecordNotFound, :with => :rec_not_found

#add the following code:
def show

if params[:id].nil?

@page = Page.find(:first)

else

@page = Page.find_by_shortname(params[:id])
raise ActiveRecord::RecordNotFound unless @page

end

end

def rec_not_found

@page = Page.find(:first)
render :action=>’show’

end

5 open app/views/layouts/application.erb and change the following line of code in the loop:

<%=link_to page.title, “/pages/”+ page.shortname  , :class => “smlink” %>

In order for the above line of code to work you have to have some other function put in which is in my other blog posts.

If you don’t have that function in, you can just hard code a link so see that it works or type it in the browser address, like this:

<a href=”/pages/profile”>Profile</a>

or see create a list of database items in admin area
for how to create a basic loop that you can put in application.erb


force rails to using show.html.erb from def index in the controller, how to

June 10, 2009

So now you have some basics put into your Web site, and you are ready to show some data to the public site. But you want to make the def index code in your controller use the show.html.erb.

1. Open pages_controller.rb

def index

@pages = Page.find(:all, :order => “page_order ASC”)

@page = Page.find(:first, :order => :page_order)
render :action=>’show’

end

This will force the use of show.html.erb when the public requests yourdomain.com/pages/

So in the query, it selects the first page in the Database. Because there is no ID sent from the path above, just /pages/ , so you gotta do this in the controller

The @pages query is for your navigation menu at the top, if you decide to make that part of your project dynamic. I’m pretty sure that I have the code somewhere in this blog to show how that works in the application view. look for listing of items in the titles for how to display that menu of page links.


Add form validation for Ruby on Rails app, for the admin namespace, a guide

March 18, 2009

This blog entry is for adding form validation to your admin section. You can also use these instructions for your public side validation.

1 open the file app/models/page.rb

Add this into the file:

validates_presence_of :shortname

validates_uniqueness_of :shortname

validates_numericality_of :page_order

validates_presence_of :title

validates_presence_of :content

If you don’t know why there is a shortname in the model, that’s ok. You may not have read the blog regarding this field. There will be a blog made for that field.

2 Open this file, or create it:  public/stylesheets/admin.css

Put this into the file, you can change it if you want:

.fieldWithErrors {

border-left: 10px solid #b00000;

width: 400px;

border-left-color:#b00000

}

.errorExplanation{

color:#b00000

}

3 Go into these files: app/views/admin/pages/edit.html.erb and new.html.erb

Make sure the following code is somewhere in the file, preferably at the top:

<font color=”red”>

<%= error_messages_for ‘page’ %> # ‘page’ is the model name

</font>

This will show error messages on your page if there is a validation error. Test it and you will see.


create simple public database driven web site in Ruby on Rails, step by step guide

March 16, 2009

This blog entry is for setting up the public site of your Web application.

You should do the administrative site first, so you can create and edit test data.

1 First, delete public/index.html

2 script/generate controller Pages show index

This is another controller in a different namespace than the admin/Pages controller. It uses the same model as the admin controller.

3 open up this file: app/controllers/pages_controller.rb

Add this code to the controller. There is a simple test here in this code, checking in case the parameter is null.

def show

if params[:id].nil?

@page = Page.find(:first, :order => :page_order)

else

@page = Page.find(params[:id])

end

end

4 open config/routes.rb

Add the following lines of code, and comment out the other lines, not needed in our app right now.

You can change your root controller later if your app changes or you want to load a different controller for the root of the application.

map.resources :pages

map.root :controller => “Pages”

#comment the next two lines out

#map.connect ‘:controller/:action/:id’

#map.connect ‘:controller/:action/:id.:format’

5 open up the app/controllers/pages_controller.rb

put this code into the index def:

def index

@page = Page.find(:first, :order => :page_order)

render :action=>’show’

end

6 create the file app/views/layouts/application.html.erb

This is where you put your main layout, made up of html code, of course.

Inside the content area of your html layout, put this line of code:

<%=yield %>

You can start out by putting only the above line of code in this file.

This will pull the layout from the views of each of the controllers. The controller executed depends on the path in the URL.

7 create the file: app/views/pages/show.html.erb

This is your view for the Pages controller. It allows you to create an html view that will fit into application.html.erb.

Put this one line of code into the file, you can build up your html around this now or later:

<%= @page.content %>

8 If you have any image files, put them into /public/images/

to reference them, use this path:

src=”/images/hdlogo.png”

9 Put your css file into /public/stylesheets/

The path to your css file is as follows:

href=”/stylesheets/style1.css”

10 see the blog post called “create a list of database items using Ruby on Rails…”, this will show you how to make a listing of links on your index.html.erb, then you can link to the above show page in application.hrml.erb. You will see how it all fits together once you do all the instructions.



Create add, edit, and show pages for administrative area, Ruby on Rails

March 12, 2009

This blog entry is for showing you how to link your admin listing page to your add, edit and show pages. There are four files that you have to make here. There is something called scaffolding, which saves you time and typing, but it’s good to drill this approach so that you understand how Rails works. Scaffolding will be posted later. But once you understand this, you should be able to figure out scaffolding yourself.

1 create or open this file: app/views/admin/pages/edit.html.erb

Put this code into the file:

<h1>Edit Page</h1>

<p>You are now editing page: <%= @page.title %></p>

<font color=”red”>

<%= error_messages_for ‘page’ %>

</font>

<% form_for([:admin, @page]) do |f| %>

<%= render :partial => “form”, :locals=>{:f=>f} %>

<p><label>&nbsp;</label><%= f.submit “Update” %>&nbsp;</p>

<% end %>

2 create or open this file: app/views/admin/pages/new.html.erb

This is the code you put into this file:

<h1>New Page</h1>

<p>You are now adding a new page:</p>

<font color=”red”>

<%= error_messages_for ‘page’ %>

</font>

<br>

<% form_for([:admin, @page]) do |f| %>

<%= render :partial => “form”, :locals=>{:f=>f} %>

<p><%= f.submit “Save” %>&nbsp;</p>

<% end %>

2 Create this file: app/views/admin/pages/_form.html.erb

Put this code into the file:

<table>

<tr><td><p><label>Title:&nbsp;</label></td><td><%= f.text_field :title %></p></td></tr>

<tr><td><p><label>Short Name:<br><small>This is the name<br>that will show in<br>the address path, <br>for About Us, <br>put aboutus</small>&nbsp;</label></td><td><%= f.text_field :shortname %></p></td></tr>

<tr><td width=”100″><label>Description:&nbsp;</label></td><td><%= f.text_field :description %></td></tr>

<tr><td colspan=”2″><label>Tags:&nbsp;</label></td></tr>

<tr><td colspan=”2″>

<%= f.text_area :tags, :cols => 50, :rows => 10 %>

</td></tr>

<tr><td colspan=”2″><p><label>Web Page Content:</label></p></td></tr>

<tr><td colspan=”2″><p><%= f.text_area :content, :cols => 100, :rows => 15 %></p></td></tr>

<tr><td width=”100″><label>Robots:&nbsp;</label></td><td><%= f.text_field :robots %></td></tr>

<tr><td><p><label>Page Order (number):&nbsp;</label></td><td><%= f.text_field :page_order, :size=>3 %></p></td></tr>

<tr><td><p><label>Enable page&nbsp;</label></td><td><%= f.check_box “showpage_flag” %> </p></td></tr>

</table>

3 Open admin/pages_controller.rb

Add the following code into the controller:

def new

@page = Page.new

end

def edit

@page = Page.find(params[:id])

end

def show

@page = Page.find(params[:id])

end

def update

@page = Page.find(params[:id])

if @page.update_attributes(params[:page])

flash[:notice] = “Page was successfully updated.”

redirect_to admin_pages_path

else

flash[:notice] = “Page was not updated.”

render :action=>”edit”

end

end

def create

@page = Page.new(params[:page])

if @page.save

flash[:notice] = ‘Page was successfully created.’

redirect_to admin_pages_path

else

flash[:notice] = ‘Page was not created.’

render :action=>”new”

end

end

def destroy

Page.delete(params[:id])  

@pages = Page.find(:all)

render :action=>”index”

end

4 create or add this file: app/views/admin/pages/show.html.erb

This is just a basic sample of how you could make a preview of some data. Add this code into the file:

<div id=”wrapper”>

<div id=”content”>

<h1><%= @page.title %></h1>

<p class=”text”>

<%= @page.content %><br />

</p>

</div>

</div>

Thats the end of this guide. I haven’t tested this to make sure it works. So if you find a bug in the code, let me know and I will update the blog entry. Now you should be able to Add, Edit, Delete and preview your data!


create a list of database items using Ruby on Rails, in the administrative area

March 12, 2009

This section shows how to make a list of items in Ruby on Rails, so that you can edit, delete, preview each item from the list. This view will also serve as the point where one can create a new Page, or whatever model you created in your project, Person, Game, Project, User, etc.

1 go into your controller file, for this blog I have been using Pages as the controller name:  app/controllers/admin/pages_controller.rb

2 find the “def index”, or create it with the following code:

def index

#use the first line for the public query

#@pages = Page.find(:all,:conditions=> {:showpage_flag => true} , :order => “page_order DESC”)

@pages = Page.find(:all,:conditions=> {:order => “page_order DESC”)

end

3 open or create this file: /app/views/admin/pages/index.html.erb

add the following code for a basic loop:

<%= link_to “New Page”, new_admin_page_path() %>&nbsp;<br>

<% @pages.each do |page| %>

<%=link_to “Edit”, edit_admin_page_path(page) %>&nbsp;

<%=link_to “Delete”, admin_page_path(page), :confirm => “Are you sure you want to delete ” + page.title + “?”, :method=>:delete %>&nbsp;

<%=link_to “Preview”, admin_page_path(page) %>&nbsp;

<%= page.title %> <br>

<% end %>

Thats all, run http://localhost:3000/admin/pages/

you should see a “New Page” link


create administrative area in ruby on rails

March 10, 2009

This blog entry is for creating a space where you can have an administrative area, where your client can access it and add, edit, remove, etc. And you can also make it password secure, which i will show in another post.


This will create the admin area, but you have to have a model created and migrated (create the database table for the model). You can make the model first, or do it after this. Find the blog entry on creating a Ruby on Rails project from Scratch, and in there it shows how to make a model and migrate it.

A migrated model can be accessed from a controller in the main namespace, or any other namespace. In this example below, it is the “admin” namespace.

1 config/routes.rb

map.namespace :admin do |admin|

admin.resources :pages

end

2 run this in your project root, in terminal:

script/generate controller admin/pages edit index new show

3 add links in administrative main menu, and create the framework

create the file views/layouts/admin.html.erb

This is your file for the  layout of the administrative area, its the framework that all your admin pages will use.

Put all this inside admin.html.erb:

<html>

<head>

<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />

<link rel=”stylesheet” type=”text/css” href=”/stylesheets/admin.css”>

<title>Company Name::Administration</title>

</head>

<body>

<h1>Company Name Administration</h1>

<a href=”/admin/pages”>Pages</a>

&nbsp;|&nbsp;<a href=”/admin/another_controller”>Another controller</a>

&nbsp;|&nbsp;<%= link_to “Log Out”, “/admin/users/show” %><br>

<%=yield%>

</body>

</html>

4 add this line into the controller, at the top, in your app/controller/admin/pages_controller.rb:

layout “admin”

Now you just need to create the model and do the migration. if you followed the blog entry on Creating a Ruby on Rails Project from Scratch, then this should be done already.

You should be able to run script/server and go to http://localhost:3000/admin/pages/

————————————————————————————–

There will be another blog entry on the admin/users controller, which will show you how to make a log in screen and a starting point for administrative users.

Also there will be a blog entry to add the security to all the controllers in the admin namespace.


Setting up Ruby on Rails project from scratch

March 5, 2009

This blog entry is for starting a Ruby on Rails project from scratch.

This entry assumes that you successfully installed Ruby on Rails onto your computer, mac or linux. This is not for windows users, although it may work.

I don’t guarantee that this will work for everyone’s environ. There may be a couple points along the way that won’t make sense, won’t work, etc. This is just a guide to help the new guy or girl get started.

1 in your home directory run this:

rails -d sqlite3 ProjectName

*note: i prefer to call my apps rails-MyProject, so all my apps are in a group in my home directory

2 go into ~/ProjectName/ directory, then run:

rake db:create

*Note: if you want to create a database model now, follow 3, 4, 5. otherwise, skip these three steps

3 in the same directory, run:

script/generate model Page

4 look into db/migrate/, there you will find a .rb file with a date timestamp, and the file should have the word Page in it.

edit the file as shown below, use :text for large blocks of text, :integer for numbers

class CreatePages < ActiveRecord::Migration

def self.up

create_table :pages do |t|

# id is created for us.

t.column :title,   :string

t.column :content, :text

t.column :page_order,   :integer

t.column :shortname, :string

t.column :showpage_flag, :boolean, :default => true

t.column :tags, :text

t.column :description, :string

t.column :robots, :string

end

end

def self.down

drop_table :pages

end

end

5 in the project directory again, run:

rake db:migrate

check the schema file in the db/ directory to verify that your table was created.

6 then open config/database.yml in a text editor, edit as below:

development:

adapter: sqlite3

database: db/development.sqlite3

timeout: 5000

test:

adapter: sqlite3

database: db/test.sqlite3

timeout: 5000

#the following data you get from your Ruby on Rails provider for your remote production application.

production:

adapter: mysql

database:

username:

password:

encoding: utf8

9 add a .gitignore file into the root of the Project directory

log/*.log

tmp/**/*

doc/api

doc/app

db/*.sqlite3

10 This is where you use git to move your project files to the remote server, and establish your local project branches. Git is pretty easy to set up. the tricky parts come when you start working with branches, merging, and pushing and pulling. Once you have git installed, you can easily follow the help files to initialize your git repository, and thus follow the step in this blog entry.

You need to set up git to push and pull your project; follow this if you have a Ruby on Rails provider or your own remote server, these instructions are for setting up git over ssh, you will need to generate ssh keys and send them to the remote administrator. For PROJECTNAME, use the name of the project as above. Your remote administrator can help you, I hope you have one.

open your .git/config file, modify as such:

[remote "origin"]

url = git@DomainNameOfProvider.com:PROJECTNAME.git

fetch = +refs/heads/*:refs/remotes/origin/*

[branch "master"]

remote = origin

merge = refs/heads/master

11 run these commands on your local computer:

git remote add origin git@DomainNameOfProvider.com:PROJECTNAME.git

# you can now do some work locally with some of the files in the project, then you should:

git add *

git commit -a (you will be prompted to type in a log entry, so write-out then exit this screen, or if VIM is used, type an entry and then :wq)

then:

git push origin master:refs/heads/master

This should set up your rails project locally and remotely with GIT. the only point that you might have to get help on is point 10, where you should have an administrator on the remote end to help you set up the remote git project. I’ve done it another way remotely, but I will put those instructions in another blog entry. Ask your administrator for help.