Saturday, September 19, 2009

Custom sql query with Activerecord

LabourEntry.all(:conditions => [sql])

Tuesday, September 15, 2009

Migrations

Docs for adding and removing columns

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

Thursday, September 10, 2009

Uninitialized Constant error on Controller

If for whatever reason you have screwed up your controller names by having singular where you should have plural or whatever, you can correct this problem through your routes file. here's a quote that helped me fix a problem with restful_authentication plugin.



for those people that used a singular Session and get the "uninitialized constant SessionsController"

So instead of
map.resource :session
use rather
map.resource :session, :controller => 'session'

Monday, September 7, 2009

Adding Restful_Authentication to all controllers (by placing in application controller)

In short add

before_filter :login_required

to ApplicationController. Then throw in an exception in SessionsController that says

before_filter :login_required, :except => [:new, :create, :destroy]

Here's the excerpt from:

http://www.erikjacobs.com/2008/12/03/authenticating-all-controllers-for-your-rails-application-with-restful_authentication/

So while this might seem intuitive, I found it a little tricky. Preliminary Google searching didn’t reveal anything inherently obvious. However, robbrit on Freenode was able to lend me a hand and I got it figured out.


As you might expect, restful_authentication’s before_filter, :login_required, will direct you to the sessions controller if you are not logged in. So, I initially applied this before_filter to the entire application by placing it as the first line in app/controllers/application_controller.rb


class ApplicationController < ActionController::Base
  before_filter :login_required

Unfortunately, this had unintended consequences. Because this requires login for *all* controllers and *all* actions, we find that we are caught in an endless loop. The login route sends us to /sessions/new, but since we are not logged in, this action tries to again send us to login. Oops!


Rails is kind enough to allow for some exceptions and other fun with filters. So, I initially realized that we should probably add an exception for the “new” action, since that is where we are redirected for a login. We add this exception by re-iterating the before_filter in the app/controllers/sessions_controller.rb:


class SessionsController < ApplicationController
  before_filter :login_required, :except => :new

Unfortunately, this did not quite cut it entirely. Do not forget that the new action essentially just renders the login form. The create action is where all of the *real* work is done. But, since we did not except create, we end up in a login loop. We can fill out the form, press the “login” button, but when we reach the create action we are not logged in. This causes the filter to fire off and send us back to… you guessed it… the new action.

Adding an additional exception (and destroy, just in case) provides the results we are looking for:


class SessionsController < ApplicationController
  before_filter :login_required, :except => [:new, :create, :destroy]

Hopefully all of this stuff will work for you, too. This is just one way I found to authenticate all controllers with restful_authentication as I had a particular application that we wanted to lock down. The extra fun with this type of stuff is that you could put a before_filter on the signup actions. This would have the effect of only allowing a user with an existing account to create new users. This is useful for development lockdown to a certain extent.

Saturday, September 5, 2009

text_field_tag ... width/size

<%= text_field_tag :skip_to, @labour_start_day, :size => 8 %>

comparison of Date with ActiveSupport::TimeWithZone failed

Great article by Mark explaining what goes wrong.

http://marklunds.com/articles/one/402

Here is a quote:

With the timezone support introduced in Rails 2.1 the idea is that all dates in the database are stored in UTC and all dates in Ruby are in a local timezone. The local timezone can be specified by config.timezone in environment.rb or set to the user timezone with Time.zone= in a before filter. Typicaly, when reading/writing from/to the database ActiveRecord will transparently convert time attributes back and forth to UTC for you. However, there is a gotcha with datetimes in ActiveRecord::Base.find conditions. They will only be converted to UTC for you if they are ActiveSupport::TimeWithZone objects, not if they are Time objects. This means that you are fine if you use Time.zone.now, 1.days.ago, or Time.parse("2008-12-23").utc, but not if you use Time.now or Time.parse("2008-12-23")

Wednesday, September 2, 2009

Install Plugin from Git - Syntax

Here's the syntax to install a plugin from git.

./script/plugin install git://github.com/rails/open_id_authentication.git

Sunday, August 30, 2009

hidden field

<%= f.hidden_field :user_id, :value => current_user.id %>

or if you don't have f

<%= hidden_field_tag(:filter_only, :value => 1) %>

Default value on select tag

When using the Rails helper select_tag, the selected value (ie highlighted value) is a parameter to options_for_select, not select_tag. Eg:

Number of Rows: <%= select_tag(:numrows, options_for_select(%w{10 20 50 100 200 500}, session[:numrows])) %>

cited from: http://soniahamilton.wordpress.com/2009/03/02/ruby-on-rails-select_tag-default-value/

Saturday, August 29, 2009

Rails Validation

Here are the docs on rails validation:

http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M002164

What is the 'h' for in rails erb?

Often you see code like:

<%=h @person.name %>

The h doesn't seem to do anything if you take it out! The h is actually important, it is the html_escape. See the documentation:

http://api.rubyonrails.org/classes/ERB/Util.html

Here is a brief quote from the docs:

html_escape(s)

A utility method for escaping HTML tag characters. This method is also aliased as h.

In your ERb templates, use this method to escape any unsafe content. For example:

puts html_escape("is a > 0 & a < 10?")
# => is a > 0 & a < 10?

Partials Naming Conventions and Best Practices

Here is a list of some suggested best practices for partials.

http://www.killswitchcollective.com/articles/13_best_practices_for_rails_partials

Here is an extended quote from that article:

Organization and naming conventions are two initial hurdles in developing effective partials. It is an easy mistake to start arbitrarily organizing and naming partial files without thinking through their roles within the application.

I think that one pitfall is using (or at least over-using) a /views/shared directory for storing partials that will be used by many controllers. I used to use the /shared folder after seeing it used in the prominent Rails books and tutorials, and initially the logic of such a directory makes sense (especially before REST became the norm). That logic breaks down, however, when virtually ALL of your partials exist in that folder! If partials are meant to be reusable and flexible, shouldn't they all be in the shared folder? This is what would happen to me, and suddenly my file names lost a lot of meaning. What does the partial shared/thumbnail show? What about shared/favorite?

Certainly you can simply use more concise naming (user_thumbnail, favorite_video) but I have found that it's best to place these partials in the view folder of the related resource. There's nothing magical about the /shared directory, it's just as easy to use :partial => 'users/thumbnail' as it is to use :partial => 'shared/user_thumbnail'. I find storing the partial in /views/users, /views/videos, etc. helps to clarify the partial's function and keeps my files in order.

Another good practice is utilizing singular and plural naming conventions. In a recent project I was using two partials with poor names: shared/user_block and shared/user_thumb. The user_block partial accepted an array of Users as the :object and passed it on as :collection to the user_thumb partial, placing it all in a wrapper. I found that a name like user_block doesn't help me remember what the partial does - does it display a block of users, or one user in a block? By renaming my partials as users/thumbs and user/thumb, respectively, I was able to clarify their purposes and make it obvious which would display a single thumb versus a collection of them.

One other pitfall is mixing up where wrapper HTML is stored. A sidebar, for example, may have a series of modules that all use a common wrapper and header markup. Some of these modules are stored in their own partials, so should the wrapper markup go inside the partial? Or should that markup stay in the view file and wrap the render method call? Either might be appropriate given any set of circumstances, but the most important thing to remember is to keep it consistent! Placing the wrapper in one partial but leaving it out of another can only lead to confusion down the road.

Saturday, August 22, 2009

Formatting Issues

Decimals

You can do it with the sprintf command. This allows only one decimal point to be shown.

sprintf("%.1f", labour_entry.hours_worked)

DateTime

Format meaning:

%a - The abbreviated weekday name (``Sun'')
%A - The full weekday name (``Sunday'')
%b - The abbreviated month name (``Jan'')
%B - The full month name (``January'')
%c - The preferred local date and time representation
%d - Day of the month (01..31)
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%p - Meridian indicator (``AM'' or ``PM'')
%S - Second of the minute (00..60)
%U - Week number of the current year,
starting with the first Sunday as the first
day of the first week (00..53)
%W - Week number of the current year,
starting with the first Monday as the first
day of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%Z - Time zone name
%% - Literal ``%'' character

t = Time.now
t.strftime("Printed on %m/%d/%Y") #=> "Printed on 04/09/2003"
t.strftime("at %I:%M%p") #=> "at 08:56AM"

Migrations after the fact ...

If you want to add a 'references' field to a table after the fact, see:

http://stackoverflow.com/questions/493777/addcolumn-for-references-rails

If you want to redo a specific migration:

rake db:migrate:redo VERISON=X

or you can redo specific operations.

rake db:migrate:up VERSION=X
rake db:migrate:down VERSION=X

Note that db:migrate:up didn't seem to work for me. I ended up adding a dummy table in the database and then running 'redo' and that seemed to work.

See. http://stackoverflow.com/questions/1316889/rails-run-specific-migration

Scaffolding

The Model name is in the singular
Use the 'references' type to refer to an existing model.

script/generate scaffold Customer first:string last:string company:string user:references

List of valid types:
:integer
:float
:datetime
:date
:timestamp
:time
:text
:string
:binary
:boolean
:decimal

http://solutions.treypiepmeier.com/2006/12/04/rails-migration-data-types/
http://dizzy.co.uk/ruby_on_rails/cheatsheets/rails-migrations

Finding Files

The following searches the current subdirectory and any subdirectory.

find -name 'mypage.htm'

You can choose to start your search from any location (the following searches from the root)

find / -name 'mypage.htm'


For more see: http://www.computerhope.com/unix/ufind.htm

Saturday, August 8, 2009

restful_authentication plugin

Needs lots of tweaking! After messing around with a lot of different suggestions, and poking around on my own this blog post seems to cover almost everything you need.

http://raindroprecords.blogspot.com/2009/01/how-to-set-up-restful-authentication.html

There seems to be problems with the internationalization option. You need to make sure that you have translations for the months because the datetime_select tag uses it. Those translations can be found at:

http://github.com/rails/rails/blob/master/activesupport/lib/active_support/locale/en.yml#L15

You put this in the en.yml under config/locales. Note that the formatting is slightly off. Under 'date:' everything is under the ':format' element. Nothing from :day_names forward should be under ':format'

Finding that piece of code

To find where a particular piece of code is, or where some class is hidden, use the nice linux feature:

find | xargs grep 'CodeToFindGoesHere'

This searches all directories recursively for that code segment.