Nathalie’s (now my fiancee) temporary position has ended last week, and she is looking for a new position in or around Bristol.
Currently working in marketing/web marketing, it’s not the best season/time to search for a new position.
With an average of 1 new job per day, I don’t think she’ll find something quickly.
I’d say that it’s normally a bad news, but this time it might be better than we thought.
Since her graduation, Nathalie always wanted to work in the web industry, That why we created SerialCooking and she was pretty good at managing the blog and the community on this project, but it was missing something: Coding.
She is now learning XHTML/CSS and web standard to have a better understanding of the whole process. And I must admit she is doing very well, and likes coding. Will she be looking for a Junior Web Developer position soon? Never know
.
She has a good understanding of technologies, web technologies and social networking.
So if you know someone who know someone with a job opportunity (Every position considered!), please let her know. Thanks a lot.
Here Nathalie Derain, online marketing executive resume in pdf.
Loosing data can be quite … annoying. (Photo on Flickr)
The last thing you want is to have a disaster on your server and being unable to recover your data.
I run all my projects and different blogs on one server, hosted by OVH. So I have multiple databases, gems, websites and configurations that I want to backup.
Hopefully, OVH provide with every dedicated server an external FTP server dedicated to backups.
So I’ve installed backup-manager and make it runs twice a day.
Because backup-manager compress your files into archives, it will cost you some space on the disk, so be sure to change the default value of the target and do your backup on a proper partition.
If you don’t, backup-manager will do the backups in / by default, so when it’ll be full, your sever will not work properly.
sudo apt-get install backup-manager
Installation create a default config file. You’ll need to edit it to match you configuration.
sudo vi /etc/backup-manager.conf
Before I explain you my config file, here is how I’ve config my server:
So basically, want I want is:
Save my /home/*, /etc/*, /opt/*, all my databases to an external partition then an external FTP.
In backup-manager.conf, you’ll need to set:
Local Storage
Backup directories
Backup transfer
Incremental Archives (set BM_ARCHIVE_METHOD = tarball-incremental)
Mysql databases
Others
Please be careful, as you’ll need to write in this file the login and password of a user to procede to dabases backups.
Don’t use root!, neither an existing user. You’re going to create a new user, with limited right on databases and tables, and you’ll protect the backup manager config file.
mysql -u root -p GRANT SHOW DATABASES,SELECT,LOCK TABLES ON *.* TO 'backupuser'@'localhost' IDENTIFIED BY 'secretpassword'; exit; sudo chown root:root /etc/backup-manager.conf sudo chmod 640 /etc/backup-manager.conf
Now you can set the 2 values in the backup-manager config file.
export BM_MYSQL_ADMINLOGIN=”backupuser”
export BM_MYSQL_ADMINPASS=”secretpassword”
Mysql database compression after dump.
export BM_MYSQL_FILETYPE=”bzip2″
Make sure that bzip2 is intalled
sudo apt-get install bzip2
Execute a command once bakcup done. You can,for example, use this to send an email after the backup.
You can use cron to schedule your backups. Before just create a little script
cat << <acronym title="End of file">EOF</acronym> > /etc/backup-manager.sh && chmod 700 /etc/backup-manager.sh #!/bin/sh test -x /usr/sbin/backup-manager || exit 0 /usr/sbin/backup-manager <acronym title="End of file">EOF</acronym>
And now you can add this script to your contab
crontab -e
And add
1 0 * * * /etc/backup-manager.sh
Here is ubuntu cron doc, easy to understand (https://help.ubuntu.com/community/CronHowto)
For example, you can call backup-manager with backup-manager -c /path/to/configfile and by this way, having 2 crons. One running every days, executing backups of files and db, and another one, in the middle of the day, only for the db
.
You can do much more than these options (cd/dvd burning for example), please be sure you read the complete wiki at http://wiki.backup-manager.org/index.php/Main_Page#Documentation
16 Jun
Posted by: Nicolas in: English, Project Development, Web Development
This year I’m looking to more networking and freelancing in the Uk, so I’ve made these business cards and they’ve been printed by Moo.
As alway, Moo quality is just fantastic, and I’m happy with the result. But I’ll certainly do another with Web Strategy Developer or something like that (more generic than Ruby on Rails evangelist).
Anyway, what do you think?
6 months ago, I decided to change my commute habits, to become greener. My bike became my principal mode of transport. And it’s really pleasant. Even in winter, you fell alive, you arrive earlier to work and at home, your not stuck in traffic. Honestly I didn’t see any inconvenient. Well, I didn’t.
I’d already realized that, sometimes, car drivers doesn’t care about cyclists. They pass us very close, they use cycle lanes or cycle part at red lights. Anyway, not really a big deal, but sometimes it can be more dangerous.
Last Friday (29th of June), a car driver simply didn’t see me, and cut my road. I hit the car back, and fall down.
First, a teenager helps me to stand up, and took my bike to the pavement, the driver took nearly 2 or 3 minutes to came out of her car. When see came out, the first think she said was : “Do you have a mobile phone to call someone?”. Well, under the shock and the pain, I said yes, and took my phone to call my fiancée 3 times. She didn’t respond (hopefully). I tried to move my right shoulder, and completely felt down under the pain. So I asked the driver to call an ambulance or the police. After going to her car taking her phone, she just asked me to call again my fiancée. Nathalie wasn’t here, so she didn’t respond. So the driver just propose me to give me a lift to the hospital (Why bloody why didn’t she wants to call someone).
She wasn’t really in panic, but I don’t know were she had her license. On the way to the hospital, she passes 2 red lights!!!.
She stopped nearly 200 meters before the hospital entrance, and said “I’ll leave you here”. The emergency room is completely the opposite!. I took her phone number, after asking 2 or 3 times, and before she left, I took a reg number.
At the BRI (Bristol Royal Infirmary), I had a very nice doctor, she took care of me, did everything. The results, right collar bone broken, tendons stretched, I’ll not be able to use my arm for 4 weeks as minimum, and really pissed off about the driver attitude.
Since we are in Bristol, it’s my second accident. Last tme we were waiting to cross a road, and hit by a drunk driver in St Augustine Parade.
I think, next time, I’ll probably remove my French flag above my head
.
So last we I didn’t code at all, I’ll try to do small things this week, but it’s really hard with one hand
.
Anyway, please, if one day you have an accident, please, take time with the victim, and be human !.
29 May
Posted by: Nicolas in: Geek Stuff, Ruby on Rails
So that’s it, you want to start development with Ruby on Rails, but you don’t know where to start.
The good thing is Ruby on Rails has a very clever and smart community, and you can find lots of documentation on the web.
Here is quick summary on where to start.
If you really want to learn Ruby on Rails, the best first thing to do is certainly to invest in a good paper/electronic book.
There are lots of books available outside but I would only recommend two of them.
Agile web development with Rails
Probably the most popular book outside. The third version include Rails 2.x support and was co-written by Sam Ruby, Dave Thomas, David Heinemeier Hansson, et al.
A must have.
The Rails Way
Obie Fernandez came here with one of the best book for rails developer. From the beginning to Rspec, you’ll learn how to start coding and testing your new Rails App. Btw, Obie Fernandez is the guy behind Thoughtbot.
New ruby on rails wiki
While your waiting your book to be delivered, you might have a look to the new ruby on rails wiki started by the Rails Activist Team. Let say, in a nutshell, that this wiki is a big FAQ for Rails, and beginners should find here responses to their questions.
Rails Guides
You know what they say, RTFM before asking a dummy question! So be sure to checkout the awesome Rails Guides before asking any question, you’ll certainly find your answer.
Official Ruby on Rails doc
Well, not the best looking, but at least it does the job.
Rails Brain
Rails brain ajaxified the official ruby doc, for a smoother search experience. The good thing is you can access on line, old Rails versions doc. Note there is also RubyBrain
Rails Searchable API Doc
A very nice Ajax interface to parse the Rails (and some other gems) api. You can download it, and copy the directory in your web server root directory to have an off line access to it.
ApiDock
Probably Certainly the best documentation search tool ever!. It combines documentation and community in the same project. Very smart. (Note there are Firefox and Textmate extensions).
Rails forum
A friendly and smart community, alway here to help. Feel free to ask your question if you didn’t find the answer above.
Ruby on Rails Google group
I’m not a big fan of malling lists/Google groups, but it’s a nice one, with -again- a huge community.
Definitively one of the best way to learn how to develop is to listen/watch some else coding.
Railscast
I don’t remember how was my Monday morning before the Railscast. Ryan Bates will offer you every week a new free screencast, full of good coding practice and advice. A must to watch, with a warm cup of tea.
Peepcode
One of the best quality screencast for Rails/Merb/Development in general. If you are new to rails, I just recommend you the REST for Rails2 screencast and the Rails2 PDF.
Rails Envy Podcast
Still need to present them? Presented by Greg Pollack and Jason Siffier Saffer Seifer (he never knows how to pronounce names either!) . These guys are just crazy, and yes it’s a compliment. Every week, during 20 minutes, you’ll learn all the hot new stuff happening in the Ruby/Rails/Merb community, with fun. Check it out.
Sure you can extend this list with blog talking about Rails, Twitters of trendy rails developers to follow, github account to watch … sure, but I think with this list above you’ll have a good entry point to the community.
Now have fun and happy coding
(go write your tests!).
18 May
Posted by: Nicolas in: English, Ruby on Rails, Web Development, tutorials
First time I wanted to use Jquery with Ruby on Rails I had some difficulties understanding how it can works.
Sure, you can easily use Jrails, that’ll brings you RJS helpers with Jquery, but I quite like the unobstrusive way, so Jrails is not (for me) the best solutions.
Let’s code together
We are going to simulate a blog post comment system. We need to be able to list the comments/create a new comment/rate a comment/delete a comment.
All this need to work with and without JavaScript enabled.
I deliberately didn’t use any user/role filtering, the goal of the code is to show of to work with Rails and Jquery
We want to work with Jquery, so we don’t need the Prototype files anymore. Just remove everything from your public/javascript/ appart application.js.
In your master layout add this bunch of lines
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<% if protect_against_forgery? %>
<script type='text/javascript'>
//<![CDATA[
window._auth_token_name = "#{request_forgery_protection_token}";
window._auth_token = "#{form_authenticity_token}";
//]]>
</script>
<% end %>
<%= javascript_include_tag 'application' %>
We are linking Jquery to the google hosted version, and calling the application.js and setting the forgery protection.
Then in your application.js copy and past the content of my default application.js (Also available as a gist)
jQuery.ajaxSetup({ 'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")} })
function _ajax_request(url, data, callback, type, method) {
if (jQuery.isFunction(data)) {
callback = data;
data = {};
}
return jQuery.ajax({
type: method,
url: url,
data: data,
success: callback,
dataType: type
});
}
jQuery.extend({
put: function(url, data, callback, type) {
return _ajax_request(url, data, callback, type, 'PUT');
},
delete_: function(url, data, callback, type) {
return _ajax_request(url, data, callback, type, 'DELETE');
}
});
jQuery.fn.submitWithAjax = function() {
this.unbind('submit', false);
this.submit(function() {
$.post(this.action, $(this).serialize(), null, "script");
return false;
})
return this;
};
//Send data via get if JS enabled
jQuery.fn.getWithAjax = function() {
this.unbind('click', false);
this.click(function() {
$.get($(this).attr("href"), $(this).serialize(), null, "script");
return false;
})
return this;
};
//Send data via Post if JS enabled
jQuery.fn.postWithAjax = function() {
this.unbind('click', false);
this.click(function() {
$.post($(this).attr("href"), $(this).serialize(), null, "script");
return false;
})
return this;
};
jQuery.fn.putWithAjax = function() {
this.unbind('click', false);
this.click(function() {
$.put($(this).attr("href"), $(this).serialize(), null, "script");
return false;
})
return this;
};
jQuery.fn.deleteWithAjax = function() {
this.removeAttr('onclick');
this.unbind('click', false);
this.click(function() {
$.delete_($(this).attr("href"), $(this).serialize(), null, "script");
return false;
})
return this;
};
//This will "ajaxify" the links
function ajaxLinks(){
$('.ajaxForm').submitWithAjax();
$('a.get').getWithAjax();
$('a.post').postWithAjax();
$('a.put').putWithAjax();
$('a.delete').deleteWithAjax();
}
$(document).ready(function() {
// All non-GET requests will add the authenticity token
// if not already present in the data packet
$(document).ajaxSend(function(event, request, settings) {
if (typeof(window.AUTH_TOKEN) == "undefined") return;
// IE6 fix for http://dev.jquery.com/ticket/3155
if (settings.type == 'GET' || settings.type == 'get') return;
settings.data = settings.data || "";
settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(window.AUTH_TOKEN);
});
ajaxLinks();
});
This is my default application.js when I want to work with Jquery.
Basically what brings you these functions are :
Any link for a class get/post/put/delete will be called via ajax only if JavaScript enabled. Same for form with ajaxForm class.
You can find the original code on my github at
http://github.com/spyou/railsjquery/tree/master
I’ve created a comment resource. The comments table has a body and a score field.
Here is the comments_controller.rb
class CommentsController < ApplicationController
#This is a virtual comment manager. There is no user detection, no session
before_filter :load_post
#This is our entry point, I'm just going to display a factice post to comment
def index
@comments = Comment.all
respond_to do |format|
format.html #we only respond to the html request
end
end
def new
@comment = Comment.new
if !request.xhr?
@comments = Comment.all
end
respond_to do |format|
format.html
format.js {render :layout => false}
end
end
def create
@comment = Comment.create(params[:comment])
respond_to do |format|
format.html { redirect_to comments_path() }
format.js {render :layout => false}
end
end
#This is not a "normal" update, I'll use this one to add points to the comment
def update
@comment = Comment.find(params[:id])
@comment.score = @comment.score + 1
@comment.save
respond_to do |format|
format.html { redirect_to comments_path }
format.js {render :layout => false}
end
end
def destroy
@comment = Comment.find(params[:id])
@comment.destroy
respond_to do |format|
format.html { redirect_to comments_path }
format.js {render :layout => false}
end
end
protected
def load_post
@post = "This is a factice post, I hope you like it. Just comment on the bottom!"
end
end
As you can see on it, we handle 2 different types of responses
respond_to do |format|
format.html
format.js {render :layout => false}
end
Format.html will load your [actionName].html.erb, but the format.js will load a page called [actionName].js.erb were you can put all the callback javascript you need.
For example here is my index.html.erb
<%=
#Use a helper to display the current comments of the post
comments_display(@comments)
%>
<div class="newComment">
<%= link_to 'Create a new comment', new_comment_path(),:class => "get"%>
</div>
and the _comment.html.erb
<div id="comment<%= comment.id %>">
<%=
content_tag(:p,
comment.body)
%>
<!-- We are accessing the update function so we use put as class -->
<span class="score"><%= comment.score %></span><span> - <%= link_to 'Add one point!',comment_path(comment),:class => "put" %></span>
<p> - <%= link_to '*Delete this comment',comment_path(comment),:method => :delete,:class => "delete" %></p>
<p><%= comment.created_at %></p>
<hr />
</div>
You can see the use of get/put/delete class.
Here is now the new.js.erb (Where I call a _form.html.erb to render the new comment form)
$(".newComment").html("<%= escape_javascript(render :partial => 'form') %>");
ajaxLinks();
And here is the update.js.erb (Where I’m suppose to update the score of the comment without refresh)
//Update the score
$('#comment<%= @comment.id %> span.score').html("<%= @comment.score %>");
Well, the problem with the test is, you can test the rendering of you page (in plain text) but you can’t be sure of the javascript execution.
I’m made some simple tests (testing the plain text) that you can find in the test/functional folder.
(Example with the new comment method)
#Testing the comment creation
context "handle :create" do
context "by html" do
setup do
post :create, :comment => { :body => "My comment" }
end
should_change "Comment.count", :by => 1
should_redirect_to("the index"){comments_path()}
end
context "by xhr" do
setup do
xhr :post, :create, :comment => { :body => "My xhr comment" }
end
should_change "Comment.count", :by => 1
should "Display the new comment link" do
assert_match(/new comment/,@response.body)
end
should "display the created new created message" do
assert_match(%(My xhr comment),@response.body)
end
end
end
This is just the beginning, I’m now looking to some Javascript testing solution for Rails, will be part of another tutorial.
So in a nutshell, what’d learn here is :
Just checkout the complete source code
git clone git@github.com:spyou/railsjquery.git rake gems:install rake db:create

I hope it was useful.
15 May
Posted by: Nicolas in: English, Project Development, Ruby on Rails, Web Development
After having released www.serialcooking.com, I needed to do something just for me (I work on serialcooking with Nathalie).
This monday, I started a web implementation of Tweetdeck, and even if it’s now finished now, it goes very quickly.
I’ve used twitter_auth, and worked on it only 2 nights currently, but I want to realease it as soon as possible (Before the end of may?).
Here is a screeshot of the actual work
So far, I’ve got the account creation working, the search, the column saving. I’ll work this week end on the group impletation and attack the facebook auth and status display next week.
You can already register to mysocialdeck.com, to be sure to have your token for the beta.
Mysocialdeck.com is going to be develop with Rails 2.32, HAML, Twitter_auth and Jquery. I’m still looking for the best javascript testing solution. The rest of the test are going to be done with shoulda and factory-girl.
What do you think of the idea? the logo? I’d really like to heard about you.
11 May
Posted by: Nicolas in: English, Project Development, Ruby on Rails, Web Development
It was the big things weeks ago, but I didn’t had time to test it. Twitter_auth, allows you to user the twitter authentication on you application. And it’s really sweet!.
Let’s do a small implementation together.
Because Twitter doesn’t allow the callback parameter anymore, you’ll need to setup your workstation.
I recommend to install passenger in your development box, and use the hosts file to manage your different applications.
For that, just follow the official passenger doc. Easy peasy.
Then you’ll need to prepare your localhost. I like to work with [applicationName].local.
sudo nano /etc/hosts
Then add an extra line
127.0.0.1 twitterauth.local
Now create your rails app
rails -d mysql twitterauth
or take my source code my github twitterauth-test
Finally add the site to apache
sudo nano /etc/apache2/sites-enabled/twitterauth
Then copy (and modify) these lines on it
<VirtualHost *:80> ServerName twitterauth.local DocumentRoot "/home/[REPLACE WITH YOU PATH]/twitterauth/public" RailsEnv development RailsAllowModRewrite off <directory "/home/[REPLACE WITH YOU PATH]/twitterauth/public"> Order allow,deny Allow from all </directory> </VirtualHost>
Restart apache
sudo /etc/init.d/apache2 restart
You now have your development box working with passenger. Next application you’ll develop, just add a new line in the /etc/hosts file, a new site-enabled file restart apache and you’re ready.
Modify you environement.rb by adding
config.gem 'twitter-auth', :lib => 'twitter_auth'
Then sudo rake gems:install, and you’ll have the gem installed.
script/generate twitter_auth rake db:create rake db:migrate touch tmp/restart.txt
In order to work properly, your app (even on development mode) need to be registered on twitter. Visit Twitter apps and form with your informations.
Twitter doesn’t accept the callback param anyone, so you’ll need to provide http://twitterauth.local/oauth_callback as a callback in the configuration form.
When you save the informations, Twitter will give you 2 keys that need to be copied in config/twitter_auth.yml.
then
touch tmp/restart.txt
Your app is now ready!
We are going to create a twitter controller, with an index action
./script/generate controller Twitter index
Twitter_auth use the REST twitter api style, so to the loggued user friend time line copy and paste this in twitter_controller.rb, and returns a Json array. (visit the twitter api wiki for more informations)
Before calling functions that need you to be logged in, you’ll have to use the login_required method on before_filter.
This is going to be our root method so add in routes.rb
map.root :controller => "twitter"
This code goes into twitter_controller.rb
before_filter :login_required
#Retreive the friend timeline
def index
@tweets = current_user.twitter.get('/statuses/friends_timeline')
logger.info @tweets
end
Then in your views/twitter/index.html.rb
<ul class="tweets"> <% @tweets.each do |tweet| %> <li><%= link_to(tweet['user']['screen_name'] + ':', 'http://twitter.com/' + tweet['user']['screen_name'], :target => '_blank') + tweet['text'] %></li> <% end -%></ul>
After a bit of CSS, if you open http://twitterauth.local you should have something like this
Today I’ve played with twitter_auth, and I must admit it’s really sweet.
As I leave for a camping trip this afternoon, I’ll not be able to write a tutorial on how to setup you development box, but I’ll do it on Monday.
You can just check my source code on github. (You’ll need to add the database.yml and the twitter_auth.yml before it works).
Have a nice week end! I’m of for the downhouse farm now.
05 May
Posted by: Nicolas in: Geek Stuff, Project Development, Ruby on Rails, Tools
This morning I needed to transform some Textmate snippets to Gedit format.
I’ve wrote a quick and dirty code for that (tmsnippets2gedit on github)
You just need to copy the script to the textmate bumdle root directory, and run it.
You’ll have a new file call result.xml that you need to edit to specify the language format (JS,Ruby,XSL, …).
Then rename it and copy it to your gedit snippets folder.
The code is not pretty, and is certainly perfectible, but for the moment it works. I’ll to combine it to the tm2gtksw2 project (this one convert Texmate styles to Gedit styles)