Uncategorized


I did PHP for 6 years.... sometimes its hard not to do PHP in ruby...

Today i was testing a url to see if it contains a certain string:

RUBY:
  1. response = Net::HTTP.get_response(URI.parse("http://myawesomesite")
  2. if response.body.match("my awesome text") == nil  then
  3.       return false
  4. end

and remember to do:

RUBY:
  1. response = Net::HTTP.get_response(URI.parse("http://myawesomesite")
  2. return "false" if response.body.match("my awesome text").nil?

Another thing I was working on was I had to do a multiple if statement

I will simplify it for this example:

RUBY:
  1. color = red
  2.   if (color == "red") or (color =="green") or (color == "yellow") then
  3.     print "its valid)
  4. end

In PHP I might have actually made the values into an array, and then did in_array ... but in reading the code, you see below, if in the valid values, print something. I don't want to see array!

This is more elegant:

RUBY:
  1. color = red
  2. valid_values = ["red","green","yellow"]
  3. puts "its valid" if valid_values.include? color

This seems to only work for values you'd do == on, not ===

See... programming in ruby just makes me grin :)

When I posted at the Rails-Forum, I also emailed the internal DevChix list (sorry boys!) because I was totally at wits end about this problem. (got no response from Rails-Forum BTW) and at least I got some ideas...

Jen-Mei said to try this:

RUBY:
  1. Out of curiosity, when you run the Ruby console, what do you get when
  2. you type:
  3.  
  4. ActiveRecord::Base.connection.native_database_types[:string]
  5.  
  6. or just
  7.  
  8. ActiveRecord::Base.connection.native_database_types
  9.  
  10. ?
  11.  
  12. This is the array that ActiveRecord should be using to convert from
  13. the type you use in your migrations to database types.
  14.  
  15. I'm running MySQL 5. When I run it, I get:
  16.  
  17.                       >> ActiveRecord::Base.connection.native_database_types[:string]
  18.                        => {:name=>"varchar", :limit=>255}
  19.  
  20. Are you getting the same? The way it's running for you, it almost
  21. seems like it's returning nil or "string".

That worked as expected!! So that was not the problem...

Sandi M. had this idea:

RUBY:
  1. Looking in rails 1.2.3, I see that
  2.  
  3.     ActiveRecord::ConnectionAdapters::ColumnDefinition (1) has method
  4.       def sql_type
  5.         base.type_to_sql(type.to_sym, limit, precision, scale) rescue type
  6.       end
  7.  
  8. If this method raises an error, you'd get your original value back for the type.
  9.  
  10. It would be really interesting to go into this bit of code and change it to
  11.  
  12.       def sql_type
  13.         begin
  14.           base.type_to_sql(type.to_sym, limit, precision, scale)
  15.         rescue Exception => e
  16.           print e.backtrace.join("\n")   
  17.           raise "type_to_sql failed with #{e.class} #{e.message} for #{type}"
  18.         end
  19.       end
  20.  
  21. One would guess, looking at the type resolution code for various adaptors, that your install is missing, or didn't load, the adapter class which contains the type translation code for your database.  This backtrace should help locate the problem.

By this point, we had taken the conversation to instant messenger..

Hmm... so I saw it trying to work... I got an error saying argument error with expecting 4 params and only getting 2! Jen-Mei had me do a grep to see if type_to_sql is defined anywhere -- and AH HA.. there was a plugin -- mysql_bigint that was installed, and it had redefined the method and that was the culprit. This was a codebase that I inherited so I didn't even know what that plugin was used for or anything.

Here was the code in mysql-bigint plugin

RUBY:
  1. def type_to_sql(type, limit = nil) #:nodoc:
  2.           mysql_integer_types = %w{tinyint smallint mediumint intger bigint}
  3.         unless self.class.method_defined? :native_database_type
  4.           native = native_database_types[type]
  5.         else
  6.           native = native_database_type(type, limit)
  7.           limit = nil if mysql_integer_types.include? native[:name] # mysql doesn't use limit to indicate bytes of storage.
  8.                                           # Need to reassign native representation below.
  9.         end
  10.         limit ||= native[:limit]
  11.         column_type_sql = native[:name]
  12.         column_type_sql <<"(#{limit})" if limit
  13.         column_type_sql
  14.       end
  15.     end

Did a bit of research and found I had an old version installed:

http://www.northpub.com/articles/2006/10/29/new-version-of-mysql_bigint-rails-plugin

Quote from the site: "I received some feedback that edge Rails broke some things in the mysql_bigint plugin . I've checked in a new version that works correctly with edge rails. Thanks to Jamie Orchard-Hayes for a patch that fixed a few of these issues!"

So, I see there's a fix for it... but upon further investigation, the plugin is not use in the application at all! So I removed it for now.

Things I learned:

  • Check your plugins
  • Don't be afraid to dive into the rails code and print stuff to logs to see whats going on
  • Don't keep plugins laying around that are not in use
  • Probably a good idea to document what plugins are used and what for in the README
  • How to actually RUN the unit tests for rails (see the readme in the test dir), this way I knew for sure that my checkout of rails worked and it was something with my application code
  • DevChix ROCK!!

Coolness

First the cool thing... and I think I have a good reason for this... I have a model that is not tied to any particular table, but is a summary table for about 8 tables. Rather than cluttering up my controller with a bunch of stuff, I am putting into a model (keeping REST in mind). I could have put it in the lib dir as a module.. but.. I thought i'd try it in the models dir, so i don't have to require it etc. And later I realized I need a bunch of fixtures for it, so I think its pretty handy as a model. Of course, I took out the base class of active record

app/model/summary.rb

RUBY:
  1. class Summary
  2.    attr_reader :date_from, :date_to
  3.    attr_writer :date_from, :date_to
  4.  
  5.   def has_dates?
  6.     (self.date_from && self.date_to) ? true : false
  7.   end
  8.  
  9.   def job_count
  10.     if self.has_dates?
  11.        Job.count(:conditions => ["completed_at BETWEEN ? and ?", self.date_from, self.date_to])
  12.     else
  13.       Job.count(:conditions => "completed_at IS NOT NULL")
  14.    end
  15.    
  16.    ...
  17. end

I might want to get the count of jobs for ALL time or a data range, so if there are dates set, it uses those. In addition to jobs, I need to do some 'not so easy" counting of other date and so i started changing my test fixtures to something like this:

test/fixtures/summary_report/jobs.yaml

RUBY:
  1. <% 1.upto(30) do |num| %>
  2. job_<%=num%>:
  3.   id: <%= num %>
  4.   created_at: <%=(Time.now - 1000).to_s(:db) %>
  5.   finished_at: <%= Time.now.to_s(:db) %>
  6.   name: One more number <%= num %> Awesome Job
  7. <% end %>

I have a bunch of other tests and I found one of them was not quite right, and my additional fixtures for the summary report messed it up. So I made a directory in test/fixtures/summary_report and then loaded the fixed in my summary test as such:

test/unit/summary_test.rb

RUBY:
  1. require File.dirname(__FILE__) + '/../test_helper'
  2.  
  3. class SummaryTest <Test::Unit::TestCase
  4.   fixtures 'summary_report/jobs',
  5.             'summary_report/people'
  6.  
  7.   def setup
  8.     @s = Summary.new
  9.   end
  10.  
  11.   def test_job_count_all
  12.     assert_equal 50, @s.job_count
  13.   end
  14.   ...

So I put fixtures for a particular set of tests in a directory in fixture. Is there a better way to do this?

Weirdness

I put it in a post I made on ruby-forum.com but here it is again:

Basically, when I try to use a rails version higher tha 1.1.6 in my vendor/rails directory my migrations don't have "varchar" they have "string" !! WTF! ... I even tried sqlite and same thing.

I've searched all over the web and mailing lists and can't find any info
on this problem.

I have a site built with Rails 1.1.6  I ran

rake rails:freeze:edge TAG=rel_1-2-3

I ran db:migrate (on a fresh database)

 rake db:migrate VERSION=1 --trace
(in /home/nola/projects/tardis/website/trunk)
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:migrate
== AddContact: migrating
======================================================
-- create_table(:contacts)
rake aborted!
Mysql::Error: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to
use near 'string DEFAULT NULL, `city` string DEFAULT NULL)
ENGINE=InnoDB' at line 1: CREATE TABLE contacts (`id` int(11) DEFAULT
NULL auto_increment PRIMARY KEY DEFAULT NULL, `name` string DEFAULT
NULL, `city` string DEFAULT NULL) ENGINE=InnoDB
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:128:in
`log'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:243:in
`execute'
/home/nola/projects/tardis/website/trunk/config/../vendor/plugins/mysql_bigint/lib/mysql_bigint.rb:32:in
`create_table'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:353:in
`create_table'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:275:in
`method_missing'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:259:in
`say_with_time'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:259:in
`say_with_time'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:273:in
`method_missing'
./db/migrate//001_add_contact.rb:3:in `real_up'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:212:in
`migrate'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:212:in
`migrate'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:335:in
`migrate'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:330:in
`migrate'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:297:in
`up'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/activerecord/lib/active_record/migration.rb:288:in
`migrate'
/home/nola/projects/tardis/website/trunk/config/../vendor/rails/railties/lib/tasks/databases.rake:4
/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:392:in `execute'
/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:392:in `execute'
/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:362:in `invoke'
/usr/lib/ruby/1.8/thread.rb:135:in `synchronize'
/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:355:in `invoke'
/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:1739:in `top_level'
/usr/lib/ruby/gems/1.8/gems/rake- 0.7.3/lib/rake.rb:1739:in `top_level'
/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:1761:in
`standard_exception_handling'
/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:1733:in `top_level'
/usr/lib/ruby/gems/1.8/gems/rake- 0.7.3/lib/rake.rb:1711:in `run'
/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:1761:in
`standard_exception_handling'
/usr/lib/ruby/gems/1.8/gems/rake-0.7.3/lib/rake.rb:1708:in `run'
/usr/lib/ruby/gems/1.8/gems/rake- 0.7.3/bin/rake:7
/usr/bin/rake:1

----------------------------

SO Basically, its trying to put in a sql create statement like this:

CREATE TABLE contacts (
 `id` int(11) DEFAULT NULL auto_increment PRIMARY KEY DEFAULT NULL,
 `name` string DEFAULT NULL,
 `city` string DEFAULT NULL
) ENGINE=InnoDB

string? when it should put in VARCHAR(255) .. weird huh?

Here's the migration:

class AddContact < ActiveRecord::Migration
  def self.up
    create_table :contacts do |t|
      t.column :name, :string
      t.column :city, :string
    end
  end

  def self.down
    drop_table :contacts
  end

Any ideas? I've also tried with rel_1-2-0 too... and get the same
result. I can create a table with ints or no fields just fine. When I
remove vendor/rails then its fine.

Hey ... a friend at oscon send me this survey PerlSurvey ... if you do perl, take it and let your voice be heard!

I was starting a redo of a old (rails 1.1.6) site and thought I'll store the rails in the vendor directory so I don't have to worry about what version is installed in the server, so I looked up this nifty Article on SitePoint where they explain how to do that. Installing and Managing Edge Rails.

I started with some basic steps to "redo" my old site.. used the controller generator.. whoa.. huh? ".html.erb" .. I instant messaged a friend, Carmelyne and said whats up with ".html.erb" .. she is like, oh thats edge rails. I thought I had installed 1.2 release instead but on closer inspection I did indeed install edge. I must have had the version number wrong or something. Doh, oh well.. let me try it anyways.

In further discussion.. she suggested i look at using REST.. "isn't it just for webservices?" i ask, she said no. I'm not doing anything that I will need to publish web services for.... its just a bakery order site. But, I did a little research and Carmelyne pointed me to some resources.... and I got it!

A lightbulb went on!

I used the scaffold in edge to build my model... looked at the controller...looked at routes.rb ... and i got it. :)

Read these to understand what the heck I am talking about:
A Series of 5 articles on REST and Rails - very basic and helped me understand how, what why of REST and Rails.
REST on Rails - another good one

I feel like I've been a bird with my head in the sand. I'd read stuff before but never understood how, what and why of REST.

More to follow as it sinks in.

I had planned to go to the Rails Conference but things came up and I've changed my mind! So I have until April 17th to transfer the ticket to another individual -- price is $745. Leave a comment here if interested.

Turns out, that not even ruby was relaxing enough for my 3 day vacation.. I didn't do much of anything on the computer. Just took a break. I spent some time outside, ordered a bike..did alot of swimming and had some fun.Now, I'm back and ready to tackle work again.

ProPHP Security

Published by: Apress

Authors: Chris Snyder and Michael Southwell

Book Site | Sample Chapter: Preventing SQL Injection | Table of Contents

At first, I thought this book was all about cleaning your input variables and filtering your output, XSS attacks, SQL injections but I was most presently surprised to find that it was that and so much more! In fact, I would have called this "ProPHP Security and Administration" instead! It is absolutely fantastic. It really is about security in all of the facets of web development - from server, to code, to database to the system users.

The book is divided into 4 parts:

- Part 1: The Importance of Security

- Part 2: Maintaining a Secure Environment

- Part 3: Practicing Secure PHP Programming

- Part 4: Practicing Secure Operations

Here are some brief overviews of the sections and the tidbits I found interesting:

Part 1:

The first part is the shortest and gives a general overview the what and why of security.

Part 2:

The second is much more hearty and goes into detail about Shared hosts and why they are secure and how to make the more so. It even dips into alternatives for the traditional shared hosts and goes into Virtual Machines. This is valuable to not only to administrators but to PHP Developers. After reading this, I understand the "why" behind many of the things about shared hosting that I found frustrating.

One of the most important things I found in this chapter is how to maintain separate development and production environments. When I was helping to set this up at one of my past jobs it was a topic that I couldn't find much information about. It also makes mention of version control, using wikis, bug tracking, sandbox and testing! Oh and here's a concept…. pretend your live system failed -- how well does your backup plan work?

How many times have I thought, I should make a cron job to back up my database to my home server every day/week? Have I ever done this? No! But now I have no excuse! Backing up a database and storing remotely is one of the sections in this chapter and code included! Fantastic.

There are chapters about Encryption theory and practice which I read several times to understand. It was interesting but it wasn't something I have to do right now in my life, but I will return to this book to refresh my memory when I do.

Securing Network connections SSL and SSH, these proved helpful as I have become the "Reluctant System Admin" for one of my projects -- partly because if they were to hire a part time person I'd rather they get a CSS person and I'd rather do the sys admin!

The Controlling Access section goes into details about using certificates with php, single sign-on, basic and digest http authentication … whoa this is some deep stuff! But good, when I was looking into this for a project a few years ago I couldn't find anything helpful. It continues with then permissions and restrictions, a lot about Unix permissions and keeping things running where they should, securing databases and PHP Safe mode!

Part 3

Finally -- the stuff that I thought the book would be about - validating user input, filtering output, preventing cross site scripting attempts, remote execution.. so much more to security than I thought! It talks about securing temp files, I always assumed the OS handled this and I didn't need to worry.

Part 4

Ahh -- Practicing Secure Operations… all you ever wanted to know about making sure your users are humans, verifying your users, setting roles for users, logging your users actions, preventing data loss, executing system commands safely, working with webservices and finally Peer Reviews! Sometimes it's that extra pair of eyes that can see things you miss.

Something I find interesting - in the section about preventing data loss, it talks about setting a flag on records that are "deleted" and then making a db view of the "good" data and using that to select from. One of the things I like in Ruby On Rails is this "acts_as_paranoid" model option that does about the same thing. Neato.

Pro PHP Security is a most excellent read and so much deeper than my brief overview here. It will be a handy book on my shelf to keep me on my toes regarding security in all areas of web development, from the server to the code, to the users, to best practices of security you will find this is a helpful book too!

Hey, I added Feedburner to this site AND to DevChix ... still learning about all I can do with it...

Tonight was fantastic! We had Chris McAvoy, fellow language geek as myself, talk about the favorite parts of his languages. He started by stating the criteria for learning a new language - from what I remember he said he likes good documentation and a good interactive console. Ruby has great both, Python too... Perl is a bit lacking in the console but does have an attempt at it using the perl debugger. Its not bad, but compared to Ruby and Python, its not so fun.

He gave brief overviews of the basic syntax and structure as well as talked about the packaging system. It was interesting, I have dabbled in Python, but have decided to master Ruby first. I do love the cleanness of Python -- very refreshing after staring at ugliness of PHP all day. PHP is fine, but after looking at ruby, man... I just can't help it..
I had to leave just when he started talking about Ruby DSLs, something that has me absolutely fascinated the past few weeks as I try to wrap my tiny brain around the concept and track down tutorials and sample code. I may have to track him down for lunch and fill me in ....
Here are links from his talk:

Notes from Meeting - like me, he also dislikes powerpoint. Nothing wrong with just a list of notes!

« Previous PageNext Page »