I don’t have a fix for it yet (admittedly, I haven’t bothered looking since I don’t have a problem with 0.9.5 as of yet), just posting
% sudo gem update –system
Updating RubyGems…
Attempting remote update of rubygems-update
Successfully installed rubygems-update-1.0.0
1 gem installed
Updating version of RubyGems to 1.0.0
Installing RubyGems 1.0.0
./lib/rubygems.rb:77: uninitialized constant Gem::RbConfig (NameError)
from setup.rb:19
I’ll probably just keep updating this post as I run across more things. It’s ostensibly as a comparison to ASP.NET 3.5 with the upcoming extensions.
Good things / Pros
Bad things / Cons
Push
I’ve found a surprising number of sites (even Ruby ones) that think it’s duct typing instead of Duck typing
I wonder why they think it’s called “duct”? Because it holds everything together like the force?
On a related note, I like how Boo allows you to choose whether you want Duck typing or not. This is a nice compromise, and it would be nice to have something like it in C#. :)
Along with the normal types like object, int, string…boo has a special type called “duck”. The term is inspired by the ruby programming language’s duck typing feature (”If it walks like a duck and quacks like a duck, it must be a duck”).
If you declare an object as type duck or cast to type duck (or turn on the implicit duck typing option, see below), then boo will not try to resolve any methods or operations you call on that object at compile time. Instead it will convert those operations into methods that do not resolve until runtime. So at compile time it simply trusts that you know what you are doing (”it walks like a duck so it must be a duck”).
As part of starting some Rails development on my linux dev box, I installed mysql-server which was up and running fine. However, once a day I was getting an email from cron about a failure:
/etc/cron.daily/mysql-server:
/etc/cron.daily/mysql-server: line 26: /etc/mysql/debian-log-rotate.conf: No such file or directory
run-parts: /etc/cron.daily/mysql-server exited with return code 1
So, apparently the daily cron script for mysql to do log rotation needs a fail /etc/mysql/debian-log-rotate.conf to exist. If that’s true, it seems like it should have come in one of the packages, so I check to see what package should have installed it:
% dpkg -S debian-log-rotate.conf
dpkg: *debian-log-rotate.conf* not found.
So, none of my packages own a file by that name, in /etc/mysql or anywhere else. So, it’s a bug that the file is needed but not present. Whatever, this is 6.06 so I’m not going to bother reporting it since I’m pretty sure this is fixed more recently in the 3 released versions since.
What to do? Well, let’s check out that script (/etc/cron.daily/mysql-server) around line 26 to see what it’s trying to do:
# Read config and see if we should rotate at all.
. /etc/mysql/debian-log-rotate.conf
if [ "$KEEP_BINARY_LOGS" -eq 0 ]; then
my_exit 0
fi
Since this is just a server to play around with and not a production system, I don’t care about keeping any logs around (I can re-create the schema, sans data, at any time with “rake db:reset:all“)
sudo vim /etc/mysql/debian-log-rotate.conf
I insert a single line of
KEEP_BINARY_LOGS=0
And that’s it - now the script will exit early, but succeed fine. And I won’t get any more cron emails about this particular failure :)
First hit for “monorail tutorial” says “Work in progress“.
Go to their trunk and hit the documentation, and there’s 3 links under “Tutorials and Hands-on labs”. Great!
Except, you know, all 3 say “Work in progress”. Monorail as a project has been around awhile. They’re very close to 1.0, even since they’re at 1.0 RC2 as I write this.
The most useful hit was at #4, a video on how to pull off the monorail move with a diabolo.
Now that I had gotten Rails 2.0 installed, it was time to make a Rails 2.0 app. I decided to go back to the original screencasts (tons of more recent ones at railscasts) and see if I could follow DHH’s original “build a blog in 15 minutes” screencast. There’s some things that don’t work any more, and more importantly, a good number of things that are significantly better/easier in 2.0 now. Here’s a list based on following the video:
File extensions
While you can still use index.rhtml, the preferred naming separates the mime-type from the rendering mechanism, so you’d be better off using index.html.erb.
http://weblog.rubyonrails.org/2007/12/7/rails-2-0-it-s-done
We’ve separated the format of the template from its rendering engine. So show.rhtml now becomes show.html.erb, which is the template that’ll be rendered by default for a show action that has declared format.html in its respond_to. And you can now have something like show.csv.erb, which targets text/csv, but also uses the default ERB renderer.
Database needed even for Hello World
In the video, he didn’t set up the database until after he already had a controller created, handling an index action (that did a render :text), and then the index.rhtml view. In Rails 2.0, you can’t do that any more, because you’ll immediately get an error on that /blog hit.
No such file or directory - /tmp/mysql.sock
You have to have the database setup before you have a working controller, even if no database access is involved at all. I’m fine with that, of course, since you need to get the database config fixed eventually for anything interesting.
Database server setup
While I don’t know for sure whether this is a Rails 2.0 thing or not, the database.yml file in the video doesn’t have a socket: line, so I’m leaning towards this being a 2.0 thing, although I’m happy to hear otherwise if that’s not the case :)
From the above error, it’s relatively obvious that rails is trying to talk to a mysql server via a socket located at /tmp/mysql.sock.
Database creation
In the video, you see him using a MySQL gui a lot for creating the database and tables and then turning around and creating the model based on it. As many others apparently agree, that’s pretty ugly that with a database abstraction layer in place, we’re still having to interact directly with the database (especially since ActiveRecord Migrations exist)
Thankfully, that’s gone in 2.0, thanks to Matt Aimonetti, and you can create the current database or all of them in a single rake command (or drop, or drop and re-create). I chose to create all 3 of them and ran rake db:create:all. Very nice!
Table creation
Also in the video, you see him use the MySQL gui for the creation of a table, as mentioned above. When I got to the “generate model Post” step, I realized this isn’t necessary any more.
Now generating the model will also generate the migration script to create the relevant table! That’s awesome! You just go edit the migration script that was generated for creating the table, which already has a shell create_table in self.up (with t.timestamps already in place! nice!) and the necessary drop_table in self.down.
% script/generate model Post
create app/models/
create test/unit/
create test/fixtures/
create app/models/post.rb
create test/unit/post_test.rb
create test/fixtures/posts.yml
create db/migrate
create db/migrate/001_create_posts.rb
% cat db/migrate/001_create_posts.rb
class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|t.timestamps
end
enddef self.down
drop_table :posts
end
end
Yes, of course, this is using the new Sexy Migrations syntax, so all I had to add to the create_table was:
t.string :title
t.text :body
(UPDATE: I now know that I could have just added title:string and body:text onto the end of the generate model command line)
Then, just run db:migrate and I had a great posts table in my database! I really like the 2 columns that t.timestamps gives you - that’s a nice touch. And notice that I didn’t have to create the id column like he did in the video.
mysql> desc posts;
+————+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+————+————–+——+—–+———+—————-+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(255) | YES | | NULL | |
| body | text | YES | | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+————+————–+——+—–+———+—————-+
5 rows in set (0.01 sec)
Most importantly, I never had to interact with MySQL directly - heck, except for the database.yml settings, I don’t even *know* that the backend is MySQL.
However, I ended up removing this migration and model due to the change in scaffolding, which I’ll cover now:
Scaffolding
In the video, he gets the scaffolding (wiki page, API doc) going in the blog controller with “scaffold :post” in the blog controller. That doesn’t work in Rails 2.0 any more. If you try to use it, you’ll get:
undefined method `scaffold' for BlogController:Class
This wasn’t covered in the 2.0 blog posts I ran across, but some other hits thought that scaffold had been removed in 2.0. Rather than guess, I checked out the changelog located at /usr/lib/ruby/gems/1.8/gems/actionpack-2.0.1/CHANGELOG to confirm, and sure enough it was intentionally removed by DHH himself.
* Removed ActionController::Base.scaffold — it went through the whole idea of scaffolding (card board walls you remove and tweak one by one).
Use the scaffold generator instead (it does resources too now!) [DHH]
So, checking the output of “script/generate scaffold” I see our example in there already:
Description:
Scaffolds an entire resource, from model and migration to controller and
views, along with a full test suite. The resource is ready to use as a
starting point for your restful, resource-oriented application.Pass the name of the model, either CamelCased or under_scored, as the first
argument, and an optional list of attribute pairs.Attribute pairs are column_name:sql_type arguments specifying the
model’s attributes. Timestamps are added by default, so you don’t have to
specify them by hand as ‘created_at:datetime updated_at:datetime’.You don’t have to think up every attribute up front, but it helps to
sketch out a few so you can start working with the resource immediately.For example, `scaffold post title:string body:text published:boolean`
gives you a model with those three attributes, a controller that handles
the create/show/update/destroy, forms to create and edit your posts, and
an index that lists them all, as well as a map.resources :posts
declaration in config/routes.rb.Examples:
`./script/generate scaffold post` # no attributes, view will be anemic
`./script/generate scaffold post title:string body:text published:boolean`
`./script/generate scaffold purchase order_id:integer amount:decimal`
Since it generates the model, migration, and controller, I go ahead and rake db:drop:all and just start the app over from scratch. As per the above, I didn’t need to add the socket: lines this time around, so right after running “rails”, I ran the above “generate scaffold” and then “rake db:create:all” and “rake db:migrate” - I end up with the same table as the first time, except now I have another column (of mysql type tinyint(1)) called “published” since I included that from the example.
Since the “generate scaffold” also generates the controller, I don’t need to create a controller myself, but it’s called PostsController instead of BlogController, so when we start the server again and hit the url, it’s /posts and not /blog. However, hitting it with the Firefox I already had running ends up with an error:
CGI::Session::CookieStore::TamperedWithCookie
We can see one of the Rails 2.0 security measures in action here - nice! I’m sure this is because my Firefox has an existing cookie from the previous incarnation of the rails app, so I’ll just clear the cookie. Tools -> Options -> Show Cookies, and I remove the cookie there:
Now I can hit /posts again and it works!
Then, adding a new post has a form now:
And clicking create shows the new post (at /posts/1), including the flash of “successfully created” - yay!
Clicking Back to get to the full list:
Adding comments
As with the first time we generated a model (even though we threw that one away), when we “script/generate model Comment”, we automatically get the migration file for adding the comments table. All we need to add is:
t.text :body
t.integer :post_id
(UPDATE: I now know that I could have just added body:text and post_id:integer onto the end of the generate model command line)
Since the screencast manually inserts the first comment, I follow that same pattern here, just for the sake of it. It’s not needed, since the next step includes creating the form that allows for inserting new comments, but I do it anyway :)
mysql> insert into comments (body, post_id) values (’my first comment!’, 1);
Query OK, 1 row affected (0.02 sec)
Following that and the edits to app/views/posts/show.html.erb, I have my comment shown and the enter-a-comment form!
Running unit tests
In the video, he mentions that tests are created when models get created and he runs “rake test_units” to run the existing unit tests, which runs fine with 2 tests, 0 failures. That fails in 2.0, unfortunately.
Don’t know how to build task ‘test_units’
Fortunately, I’ve noticed a pattern in other places where underscores were replaced with colons, since “rake db_migrate” is now “rake db:migrate”, and “rake test:units” works fine with the expected results.
Finished in 0.346111 seconds.
2 tests, 2 assertions, 0 failures, 0 errors
I went to change the test_truth test in test/unit/post_test.rb like his and came to realize a few of things:
One thing I noticed after doing the initial run of the tests is that running the test:units created the tables and inserted the fixture data already - nice!
mysql> select * from posts;
+———–+———-+——–+———–+———————+———————+
| id | title | body | published | created_at | updated_at |
+———–+———-+——–+———–+———————+———————+
| 953125641 | MyString | MyText | 0 | 2007-12-14 14:51:48 | 2007-12-14 14:51:48 |
| 996332877 | MyString | MyText | 0 | 2007-12-14 14:51:48 | 2007-12-14 14:51:48 |
+———–+———-+——–+———–+———————+———————+
2 rows in set (0.00 sec)
This data comes from the default fixture file created back when I did the scaffolding:
% cat test/fixtures/posts.yml
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.htmlone:
title: MyString
body: MyText
published: falsetwo:
title: MyString
body: MyText
published: false
Nice - so, I pick the id of one of the posts that was inserted and use that for my test:
def test_adding_comment
post = Post.find(953125641)
post.comments.create :body => ‘new comment’
post.reload
assert_equal 1, post.comments.length
end
Run the tests again, and it passes. I change the post id to 1 for a moment just to make sure it fails, and it does :)
script/console
I try ./script/console like in the screencast, only to get an error of irb: command not found. Easy enough to fix with sudo apt-get install irb :)
I do the same interaction with doing a Post.find to get the post, modifying its title, saving it, then checking /posts/1 to see that the change is reflected. Then I also did the p.comments.create :body => ‘this comment comes via console’, and that showed up fine as well (didn’t need to p.save - I guess the save is implied if you’re making a change through a relationship? i’ll figure that out later). Nice.
That’s it!
Ok, this blog post has gone on long enough. Hopefully someone finds it useful, even if only as a brain dump from me going through this process. :)
Dear Amazon.com customer,
We recently noticed one or more attempts to log in to your account from a foreign IP address. If you accessed your account while travelling, the unusual login attempts may have been initiated by you. However, if you did not initiate the logins, please visit Amazon.com Inc. as soon as possible to verify your identity.
This is a security measure that will ensure that you are the only person who can access your Amazon account. Thank you for your patience as we work together to protect your account.
To get started, please click the link below and login to your account:
https://www.amazon.com/gp/yourstore/ref=pd_irl_gw/ie=UTF8&signIn=1
Best Regards,
Amazon.com Inc. Security Center
At least at first glance, it looks pretty believable (I’ll ignore the misspelled “traveling” as a hint, since “real” companies misspell as well, even AMZN I’d imagine :). It sounds like a legitimate security concern, and certainly something a “regular user” would potentially believe.
So, let’s investigate this email and find the hints that this is a phishing attack and not an actual security email from Amazon.
Who is it from?
Clicking show details at the top, I can see more of the email headers, and that’s our first hint, as Amazon wouldn’t be sending email from a place that’s not an Amazon domain, certainly not a Lycos domain in the UK.
Next step, let’s hover over that link near the bottom of the email to see where it would actually take us. Another red flag, as it goes to a different address than it appears to go to via the text in the link - the destination isn’t even on amazon.com. Smells phishy!
This particular hint can be foiled in the general case as links can have attributes that change what the status text is when they’re hovered over. Maybe gmail prevents that? Don’t know, but I wouldn’t trust it just if it happened to match.
Next step - let’s view the “raw” original email:
Scanning the headers of the original, here’s some that stick out to me:
X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2600.0000 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 X-Virus-Scanned: Symantec AntiVirus Scan Engine
No sizable company, especially Amazon, is going to be sending emails like that via Outlook Express. Are you kidding me? I would say that them using Windows for
<a href="http://www.amazrock.byethost13.com” target=_blank>https://www.amazon.com/gp/yourstore/ref=pd_irl_gw/ie=UTF8&signIn=1</a>
There’s the link that actually takes you to the phishing site.
Let’s look at the last (in the order in the email) Received header, since that’s where the email originated from:
Received: from User (cpe-74-74-67-247.stny.res.rr.com [74.74.67.247]) by ms-smtp-02.nyroc.rr.com (8.13.6/8.13.6) with SMTP id lBECfmVg008564; Fri, 14 Dec 2007 07:42:08 -0500 (EST) Message-Id: 200712141242.lBECfmVg008564@ms-smtp-02.nyroc.rr.com
It would be pretty hard to believe the Seattle-based Amazon (or again, any company of that size) would be sending email from a residential cable modem (RoadRunner), especially one in the state of New York.
Date: Fri, 14 Dec 2007 14:42:09 +0200
A timezone of GMT+2 is definitely another cause for suspicion since Seattle is currently GMT-8 and New York is currently GMT-5 (we’re not in Daylight Saving Time any more). It lines up far better with the UK email address (which points to the stny.res.rr.com probably being an open mail proxy, perhaps).
Anyway, hopefully that’s enough identification points. Now to let gmail know it’s a phishing attack:
then confirming:
My server machines run Drake server edition because of the 5 years of support (not a fan of upgrading all the servers every 6 months - the machines used to run Debian stable), which as you can tell comes with (ancient) rails 1.1.2 and nothing of rubygems (the vim version is even 6.4, although you can get vim 7.0 via the dapper backports). I wanted to start playing around with rails, so I installed it and made a simple enough app.
However, after reading about some of the new things in 2.0, I decided that I didn’t want to learn on 1.1.2 and then have to learn 2.0 differences, and might as well just start with 2.0.
Steps to get Rails 2.0 onto a Dapper Drake machine
sudo apt-get remove rails
That’s it - rails 2.0 is installed, so it was time to kick the tires and try a rails 2.0 app.
[powered by WordPress.]
jour·nal n. A personal record of occurrences, experiences, and reflections kept on a regular basis; a diary.
95. We are waking up and linking to each other. We are watching. But we are not waiting.
— The Cluetrain Manifesto
23 queries. 1.643 seconds