At the command line on your local computer
1. ssh-keygen -t rsa
2. Enter a passphrase
3. scp ~/.ssh/id_rsa.pub user@remotehost.com:~/.ssh/id_rsa_temp.pub
(will need to enter your password for user@remotehost here)
Then
4. ssh user@remotehost
5. chmod ~/.ssh 700
6. cat ~/.ssh/id_rsa_temp.pub >> ~/.ssh/authorized-keys
7. rm ~/.ssh/id_rsa_temp.pub
8. chmod 600 ~/.ssh/authorized_keys (not strictly necessary)
9. log out of your shell
10. log back in
11. ssh user@remotehost.com (should now be prompted for key passphrase)
To set it up so you can log in with no passphrase:
1. ssh-agent bash
2. ssh-add (then enter key passphrase)
3. ssh user@remotehost.com
Tuesday, September 30, 2008
Ferret on shared hosting
I'm using ferret for a full text search on an app deployed on site5. These are the steps I took to get it set up:
1. Install the ferret gem
2. Tell the rails app where to find the gem:
It seems that it is necessary to do this in environment.rb and not in config/environments/production.rb.
3. On shared hosting you can't run daemons so the DRb server approach for updating the ferret index won't work. I followed instructions here to set up a rake tast to update the index instead. I also commented out the production part in config/ferret_server.yml.
I then call this in my code via:
as detailed in this railscast.
1. Install the ferret gem
2. Tell the rails app where to find the gem:
# config/environment.rb
# Be sure to restart your server when you modify this file
# Uncomment below to force Rails into production mode when
# you don't control web/app server and can't set it the proper way
ENV['RAILS_ENV'] ||= 'production'
if ENV['RAILS_ENV'] == 'production'
ENV['GEM_PATH'] = '/home/forfolks/gems:/usr/lib/ruby/gems/1.8'
endIt seems that it is necessary to do this in environment.rb and not in config/environments/production.rb.
3. On shared hosting you can't run daemons so the DRb server approach for updating the ferret index won't work. I followed instructions here to set up a rake tast to update the index instead. I also commented out the production part in config/ferret_server.yml.
# app/models/product.rb
def before_save
# disable automatic ferret indexing...move it to a cron job
self.disable_ferret(:always)
end# ferret_index.rake
desc "Updates the ferret index for the application."
task :ferret_index => [ :environment ] do | t |
Product.rebuild_index
# here I could add other model index rebuilds
puts "Completed Ferret Index Rebuild"
endI then call this in my code via:
system "rake ferret_index &"as detailed in this railscast.
Monday, September 29, 2008
Tuesday, September 16, 2008
Rails ActionMailer on Site5 2
So, it turned out that it wasn't as straight forward as I thought. I dumped the config stuff after the 'Rails::Initializer.run do |config| ' part in environment.rb and tried to send an email. The server timed out and gave a 'Rails Application failed to start' error, which meant that the fcgi process was being killed (I looked in the site's error log in Backstage to figure this out.)
Couldn't work out what was going on, because it had worked in the console. Eventually I went back to the console. I tried
to see what settings it was reading. It dumped a load of default-looking settings to the command line. Somewhere my configuration settings were being over-ridden.
Eventually I discovered that this was happening in config/initializers/mail.rb. It seems that the initializers are run after the main initializer stuff in environment.rb. I put my config stuff in there instead and it worked :) .
Couldn't work out what was going on, because it had worked in the console. Eventually I went back to the console. I tried
ActionMailer::Base.smtp_settingsto see what settings it was reading. It dumped a load of default-looking settings to the command line. Somewhere my configuration settings were being over-ridden.
Eventually I discovered that this was happening in config/initializers/mail.rb. It seems that the initializers are run after the main initializer stuff in environment.rb. I put my config stuff in there instead and it worked :) .
Wednesday, September 10, 2008
Rails ActionMailer on Site5
ActionMailer is the rails class that allows you to send emails from within a rails app. To get it working I did the following:
1. Visit the 'Backstage' admin area and create an email account for 'email_user' with password 'email_password'. At this point it should tell you the SMTP server is 'mail.mydomain.com'.
At this stage I decided that I would try to get it working in the console first. So I went to my application root and typed 'script/console production' and then
2. Set the configuration
3. Created a mailer
This relied on the (blank) template 'App/Views/Page/about.html.erb' existing in my application folder.
4. Sent the message
This then sent me the message. Which I thought was pretty cool.
1. Visit the 'Backstage' admin area and create an email account for 'email_user' with password 'email_password'. At this point it should tell you the SMTP server is 'mail.mydomain.com'.
At this stage I decided that I would try to get it working in the console first. So I went to my application root and typed 'script/console production' and then
2. Set the configuration
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => "localhost",
:port => 25,
:authentication => :login,
:user_name => 'email_user+mydomain.com',
:password => 'email_password'
}3. Created a mailer
class Page < ActionMailer::Base
def about
recipients 'tom.closeman@gmail.com'
subject "Wey hey - it works - again"
from "email_user@forfolkssake.com"
end
end
This relied on the (blank) template 'App/Views/Page/about.html.erb' existing in my application folder.
4. Sent the message
Page.deliver_about
This then sent me the message. Which I thought was pretty cool.
Copying production data to development environment
I wanted to copy all the data from the production environment on the server to my development environment on my laptop. The following worked:
1. In the Backstage area of site5 choose SiteAdmin > Web Site Tools > Download an SQL database backup and then choose the development database.
This produces an SQL dump of the database and all the data therein.
2. Download and save this file (say we save it as 'production_dump.sql' in 'some_path')
3. Run the following
(Syntax is "mysql -hHOSTNAME -uUSER -pPASSWORD DATABASE < DUMPED_TEXTFILE")
4. Download any files that may have been uploaded to the server using facilities such as attachment_fu.
1. In the Backstage area of site5 choose SiteAdmin > Web Site Tools > Download an SQL database backup and then choose the development database.
This produces an SQL dump of the database and all the data therein.
2. Download and save this file (say we save it as 'production_dump.sql' in 'some_path')
3. Run the following
mysql -h localhost -u root -p password myapp_development < some_path/production_dump.sql
(Syntax is "mysql -hHOSTNAME -uUSER -pPASSWORD DATABASE < DUMPED_TEXTFILE")
4. Download any files that may have been uploaded to the server using facilities such as attachment_fu.
Monday, September 8, 2008
Making methods available to helpers
I recently followed the instructions here to help set up restful authentication on an application. As part of the process an 'authenticated_system.rb' file is added to the 'lib' folder containing the module 'AuthenticatedSystem'. This is then included in the application with the line
I wanted some of my views to change depending on whether on not someone was logged in as an admin. The module provided me with a logged_in? function that I could use like this to check if someone was logged_in so I thought it would be pretty straight-forward. I dutifully created an admin? function in the AuthenticatedSystem module and tried to use it in my views/helpers. Unfortunately this gave me the following error:
It turned out what I was missing was the equivalent to this:
I think what is happening here is that we're actually modifying (adding methods to) the base instance of the class we're being placed into (presumably ActionController::Base). Normally when including a module the methods are just added to the current class. Somehow the methods in ActionController::Base seem to be available to the Helpers/Views (ie find their way into ActionView) whereas those just added to the ApplicationController don't.
class ApplicationController < ActionController::Base
...
include AuthenticatedSystem
I wanted some of my views to change depending on whether on not someone was logged in as an admin. The module provided me with a logged_in? function that I could use like this to check if someone was logged_in so I thought it would be pretty straight-forward. I dutifully created an admin? function in the AuthenticatedSystem module and tried to use it in my views/helpers. Unfortunately this gave me the following error:
undefined method `admin?' for #
It turned out what I was missing was the equivalent to this:
# Inclusion hook to make #current_user and #logged_in?
# available as ActionView helper methods.
def self.included(base)
base.send :helper_method, :current_user, :logged_in?
end
I think what is happening here is that we're actually modifying (adding methods to) the base instance of the class we're being placed into (presumably ActionController::Base). Normally when including a module the methods are just added to the current class. Somehow the methods in ActionController::Base seem to be available to the Helpers/Views (ie find their way into ActionView) whereas those just added to the ApplicationController don't.
Sunday, September 7, 2008
Useful rails things
Group by week: As described here, in rails enumerable objects have a group_by method so you can do things like:
<% @posts.group_by(&:week).each do |week, posts| %>
<div id="week">
<h2>Week <%= week %></h2>
<%= render :partial => 'post', :collection => @posts %>
</div>
<% end %>
Wednesday, August 20, 2008
Attachment_fu goes to index instead of create in production
I am using attachment_fu to allow image uploading in my application. In my development environment on my local machine everything worked fine. However, on the production server I would press 'create' on the upload image form and it would just list the images without showing my new image.
I had a look in the rails log (in myapp/logs/production.log) to see what was going on. I could see the request for the new controller, but this was followed directly by an index request. For some reason there was no create request.
After some digging about I found that this was to do with how the routes and the webserver were playing together.
Rails uses restful routes to decide which controller to call. If you go to the url 'myapp.com/images' with a GET request it calls the 'index' controller whereas with a POST request it will call the 'create' controller. Somehow the POSTness of my request was getting lost.
The reason for this was due to the way the apache handles its own routing (from http://www.ruby-forum.com/topic/103619):
So to fix the problem we need to fix the trailing slash issue. I found a few suggestions on how to do this.
In investigating each of these solutions I used the Net console provided by the Firebug firefox extension in order to view the requests as they left the browser and see if the trailing slash was present or not.
The first was to put the following inside the 'controllers/application.rb' class:
This didn't seem to work for me. Not entirely sure why. It didn't cause a slash to be added and caused 'wrong number of arguments' errors on some of my routes.
The second was to put
in your .htaccess file on your server to stop apache appending the slash. I decided against this option as .htaccess files scare me a little.
Instead I set the trailing_slashes option only on the image submit form:
This seemed to work.
I had a look in the rails log (in myapp/logs/production.log) to see what was going on. I could see the request for the new controller, but this was followed directly by an index request. For some reason there was no create request.
After some digging about I found that this was to do with how the routes and the webserver were playing together.
Rails uses restful routes to decide which controller to call. If you go to the url 'myapp.com/images' with a GET request it calls the 'index' controller whereas with a POST request it will call the 'create' controller. Somehow the POSTness of my request was getting lost.
The reason for this was due to the way the apache handles its own routing (from http://www.ruby-forum.com/topic/103619):
When your form is created, the action is "/files". When this post
request hits the Grid, Apache sees that request (http://app.com/files)
and that there is a directory there, and so appends a slash (http://
app.com/files/) and redirects the browser to the new URL. This is
standard Apache behavior since most requests for a directory name are
usually for the directory's contents rather than the directory itself.
Since Apache does the redirect, the post turns into a get before your
Rails application even has a chance to see it. To test this out,
rename your files directory to any other name and you will see that
the post request starts working again.
So to fix the problem we need to fix the trailing slash issue. I found a few suggestions on how to do this.
In investigating each of these solutions I used the Net console provided by the Firebug firefox extension in order to view the requests as they left the browser and see if the trailing slash was present or not.
The first was to put the following inside the 'controllers/application.rb' class:
def default_url_options(options)
{ :trailing_slash => true }
end
This didn't seem to work for me. Not entirely sure why. It didn't cause a slash to be added and caused 'wrong number of arguments' errors on some of my routes.
The second was to put
DirectorySlash Off
in your .htaccess file on your server to stop apache appending the slash. I decided against this option as .htaccess files scare me a little.
Instead I set the trailing_slashes option only on the image submit form:
form_for(@image, :url => {:action => 'create', :trailing_slash => true}, :html => { :multipart => true })
This seemed to work.
Tuesday, August 19, 2008
Adding a text editor to a rails app
In an app I am building I need to give the user the ability to create well fashioned html in an easy way.
My first attempt was to use the textile markup language, using the acts_as_textiled plugin. This was alright but requires that the users learn a markup language that is not completely intuitive. I also had to install the Redcloth gem, which I wasn't entirely sure would be easy to install on the platform I was deploying to. I decided to look for another option.
After reading this article I decided to opt for the tinyMCE option. This was mainly because on the demo widgEditor didn't seem to remember any picture resizing that went on. Following the instructions here I performed the following steps to get the editor working (mostly shamelessly copied from the instructions in the linked blog).
1. Download TinyMCE
2. Make a new folder in your rails app: ‘public/javascripts/tiny_mce’
3. Copy the contents of the ‘jscripts/tiny_mce’ folder from the download into this new folder in your rails app. (So now you should have a folder in your rails app: ‘public/javascripts/tiny_mce/’ which contains the ‘langs’, ‘plugins’ and ‘themes’ folders, amongst other things.)
4. Make a new file: ‘public/javascripts/mce_editor.js’ and add your TinyMCE initialisation code, e.g.
(Get more information on the TinyMCE API and configuration options from the TinyMCE wiki)
As I wanted the TinyMCE editor to only apply to to a single text_area (on a page of several) I added the line "editor_selector: mce-editor", to select only text_areas with a css class = "mce-editor".
5. Add a method to the application helper
6. In the application layout (views/layouts/application.rhtml), yield the appropriate contents. According to this TinyMCE wiki page the order of javascript files is important.
7. Now, to use tinymce in a view or layout, just make a call to the new helper method e.g.
8. Although TinyMCE does do some tidying up of the html code, you will also want to add white-listing to your implementation to prevent people submitting anything dodgy. (Note that for some of the more advanced TinyMCE formatting, you will need to allow the “style” attribute in your whitelist).
This was as simple as doing
and changing the html-enabled fields from
to
and restarting the webserver (!).
My first attempt was to use the textile markup language, using the acts_as_textiled plugin. This was alright but requires that the users learn a markup language that is not completely intuitive. I also had to install the Redcloth gem, which I wasn't entirely sure would be easy to install on the platform I was deploying to. I decided to look for another option.
After reading this article I decided to opt for the tinyMCE option. This was mainly because on the demo widgEditor didn't seem to remember any picture resizing that went on. Following the instructions here I performed the following steps to get the editor working (mostly shamelessly copied from the instructions in the linked blog).
1. Download TinyMCE
2. Make a new folder in your rails app: ‘public/javascripts/tiny_mce’
3. Copy the contents of the ‘jscripts/tiny_mce’ folder from the download into this new folder in your rails app. (So now you should have a folder in your rails app: ‘public/javascripts/tiny_mce/’ which contains the ‘langs’, ‘plugins’ and ‘themes’ folders, amongst other things.)
4. Make a new file: ‘public/javascripts/mce_editor.js’ and add your TinyMCE initialisation code, e.g.
tinyMCE.init({
theme:"advanced",
mode:"textareas",
plugins : "safari",
...
});
(Get more information on the TinyMCE API and configuration options from the TinyMCE wiki)
As I wanted the TinyMCE editor to only apply to to a single text_area (on a page of several) I added the line "editor_selector: mce-editor", to select only text_areas with a css class = "mce-editor".
5. Add a method to the application helper
def use_tinymce
@content_for_tinymce = ""
content_for :tinymce do
javascript_include_tag "tiny_mce/tiny_mce"
end
@content_for_tinymce_init = ""
content_for :tinymce_init do
javascript_include_tag "mce_editor"
end
end
6. In the application layout (views/layouts/application.rhtml), yield the appropriate contents. According to this TinyMCE wiki page the order of javascript files is important.
<%= javascript_include_tag "prototype" %>
<%= yield :tinymce %>
<%= javascript_include_tag "scriptaculous" %>
<%= javascript_include_tag "effects" %>
<%= javascript_include_tag "controls" %>
<%= yield :tinymce_init %>
7. Now, to use tinymce in a view or layout, just make a call to the new helper method e.g.
<% use_tinymce -%>
<%= textarea_tag :foo, :bar, ... :class => "mce-editor" %>
8. Although TinyMCE does do some tidying up of the html code, you will also want to add white-listing to your implementation to prevent people submitting anything dodgy. (Note that for some of the more advanced TinyMCE formatting, you will need to allow the “style” attribute in your whitelist).
This was as simple as doing
script/plugin install http://svn.techno-weenie.net/projects/plugins/white_list/
and changing the html-enabled fields from
<%=h @band.description %>
to
<%= white_list @band.description %>
and restarting the webserver (!).
Monday, August 18, 2008
Setting up a rails app on Site5
This is an article describing how to set up a rails app on site5 with FCGI. It is just a basic set up. Hopefully a Capistrano deployment article will follow shortly.
First you need to set up the databases your application will use. Do this in the Backstage admin area. You will need the names of the databases later to put into your database.yml file.
You also need to have ssh access to the server. You might need to submit a support ticket to have this enabled. To see if you have ssh access attempt to log in: go to an ssh terminal (eg putty on windows or the standard terminal on mac/linux) and type
If you have ssh access you should then be prompted on whether you want to recognise the site's key (if it is the first time you have visited it) and then for your password. On logging in you should be presented by a command line prompt in your terminal. This is how we are going to interact with the server to set up the app.
You then need to upload your app to the server. I used an FTP client for this and uploaded it into a file called "apps" in my home directory on the server.
Navigate into your app folder on the server:
Set the correct permissions on the application files (not sure if these are the best permissions to set, but it works):
The files dispatch.cgi, dispatch.fcgi and dispatch.rb in the myapp/public directory are somehow involved in loading the cgi/fcgi/rb processes for serving the web app. We need to tell these where to find ruby, which is different on the server to where it (probably) is on your local computer. Change the first line of each of these files to
If you now navigate to the myapp/public file and run
you should get the html associated with your application root (identified through map.root in config/roots.rb) spat into your terminal window.
Go to the myapp/config/environment.rb file and uncomment the
line, to put the rails app into production mode.
We also need a .htaccess file in the myapp/public directory to tell requests that get redirected to this directory to be handled by the fcgi process. This .htaccess file used to be generated by the rails scaffolding but, from rails 2.0.1 onwards, isn't anymore. I used the following .htaccess file taken from an earlier app:
Either upload this file using ftp or use a command line text editor (eg vi/nano/emacs) to create and save it.
We now need to provide a symlink so that users visiting yourdomain.com will be redirected to the public file in your app (and then dealt with via the fcgi handler) instead of just seeing whatever is in your ~/public_html folder. I did the following:
Note: it is important to use a different name as symlinks seem to get upset if you use names that are too similar.
We also need to have a .htaccess file in this folder to tell the web server to use the symlink. Upload/create the following file to the ~/public_html directory:
Now by visiting yourdomain.com/another_name_for_myapp you should be directed to the root of your application.
You will need to put your database settings into your database.yml file and then create and migrate your databases.
First you need to set up the databases your application will use. Do this in the Backstage admin area. You will need the names of the databases later to put into your database.yml file.
You also need to have ssh access to the server. You might need to submit a support ticket to have this enabled. To see if you have ssh access attempt to log in: go to an ssh terminal (eg putty on windows or the standard terminal on mac/linux) and type
ssh user@yourdomain.com
If you have ssh access you should then be prompted on whether you want to recognise the site's key (if it is the first time you have visited it) and then for your password. On logging in you should be presented by a command line prompt in your terminal. This is how we are going to interact with the server to set up the app.
You then need to upload your app to the server. I used an FTP client for this and uploaded it into a file called "apps" in my home directory on the server.
Navigate into your app folder on the server:
cd ~/apps/myapp
Set the correct permissions on the application files (not sure if these are the best permissions to set, but it works):
chmod -R 755 myapp
The files dispatch.cgi, dispatch.fcgi and dispatch.rb in the myapp/public directory are somehow involved in loading the cgi/fcgi/rb processes for serving the web app. We need to tell these where to find ruby, which is different on the server to where it (probably) is on your local computer. Change the first line of each of these files to
#!/usr/bin/ruby
If you now navigate to the myapp/public file and run
./dispatch.fcgi
you should get the html associated with your application root (identified through map.root in config/roots.rb) spat into your terminal window.
Go to the myapp/config/environment.rb file and uncomment the
ENV['RAILS_ENV'] ||= 'production'
line, to put the rails app into production mode.
We also need a .htaccess file in the myapp/public directory to tell requests that get redirected to this directory to be handled by the fcgi process. This .htaccess file used to be generated by the rails scaffolding but, from rails 2.0.1 onwards, isn't anymore. I used the following .htaccess file taken from an earlier app:
# General Apache options
AddHandler fastcgi-script .fcgi
AddHandler cgi-script .cgi
Options +FollowSymLinks +ExecCGI
# If you don't want Rails to look in certain directories,
# use the following rewrite rules so that Apache won't rewrite certain requests
#
# Example:
# RewriteCond %{REQUEST_URI} ^/notrails.*
# RewriteRule .* - [L]
# Redirect all requests not available on the filesystem to Rails
# By default the cgi dispatcher is used which is very slow
#
# For better performance replace the dispatcher with the fastcgi one
#
# Example:
# RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
RewriteEngine On
# If your Rails application is accessed via an Alias directive,
# then you MUST also set the RewriteBase in this htaccess file.
#
# Example:
# Alias /myrailsapp /path/to/myrailsapp/public
# RewriteBase /myrailsapp
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
# In case Rails experiences terminal errors
# Instead of displaying this message you can supply a file here which will be rendered instead
#
# Example:
# ErrorDocument 500 /500.html
ErrorDocument 500 "Application error
Rails application failed to start properly"
Either upload this file using ftp or use a command line text editor (eg vi/nano/emacs) to create and save it.
We now need to provide a symlink so that users visiting yourdomain.com will be redirected to the public file in your app (and then dealt with via the fcgi handler) instead of just seeing whatever is in your ~/public_html folder. I did the following:
cd ~/public_html
ln -s ~/apps/myapp/public another_name_for_myapp
Note: it is important to use a different name as symlinks seem to get upset if you use names that are too similar.
We also need to have a .htaccess file in this folder to tell the web server to use the symlink. Upload/create the following file to the ~/public_html directory:
Options +FollowSymLinks +ExecCGI
RewriteEngine On
Now by visiting yourdomain.com/another_name_for_myapp you should be directed to the root of your application.
You will need to put your database settings into your database.yml file and then create and migrate your databases.
Subscribe to:
Comments (Atom)