Toggling a Div On/Off and Setting Default State

In order to have a section of a webpage toggle on and off, I need to use the toggle function that is provided by jquery.

In this example, the search partial is turned on or off with the Hide/Show Search link. When you first visit the page, the partial is shown.

<%= link_to_function 'Hide/Show Search', "$('#search').toggle()" %>


However, I wanted the page to default to the search partial not being shown. To do that, add the style to the div as below.

<%= link_to_function 'Hide/Show Search', "$('#search').toggle()" %>


Nested Attributes, Forms and Validations

I have a simple app where people can apply for a position. The table for this is applicants. Then, all users are allowed to rate each applicant. The ratings are in a table called ratings, which just has an applicant_id, user_id and score. So our tables are:

class Applicant < ActiveRecord::Base  
  has_many  :ratings
  accepts_nested_attributes_for :references, :allow_destroy => true

class User < ActiveRecord::Base
  has_many  :ratings

class Rating < ActiveRecord::Base
  belongs_to  :user
  belongs_to  :applicant
  validates_uniqueness_of :applicant_id, :scope => :user_id

The validates_uniqueness_of line is there to make sure that each user can only give one rating for each applicant.

Users edit the applicant to add their score. Since the rating is a nested attribute, we use a fields_for line in the form. Originally, I had something that looked like this:

	<%= f.fields_for :ratings, @my_rating do |builder| %>
		<%= builder.collection_select :score, Rating::SCORES, :to_s, :humanize %> 
		<%= builder.hidden_field :user_id, :value => current_user.id %>
	<% end %>

And, in the controller, my edit method looked like this:

  def edit
    @applicant = Applicant.find(params[:id])
    @applicant.ratings.build
  end

This worked, in that the ratings field was updated as the form was updated. But there was a problem. When a user went to edit their score (or put in their first score), scores from all users for that applicant showed in the form. This was NOT the behavior I wanted. Users should see only their own rating, if they want to edit it. And if they haven't yet rated that applicant, they should just see one spot for their rating.

I fixed things by changing the controller to this:

  def edit
    @applicant = Applicant.find(params[:id])
    @my_rating = Rating.where(:applicant_id => params[:id]).where(:user_id => current_user.id)
    if @my_rating.empty?
      @my_rating = @applicant.ratings.build
    end
  end

and the form to this:

	<%= f.fields_for :ratings, @my_rating do |builder| %>
		<%= builder.collection_select :score, Rating::SCORES, :to_s, :humanize %> 
		1 is the highest ranking, 5 is for candidates to reject
<% if builder.object.user_id.nil?%> <%= builder.hidden_field :user_id, :value => current_user.id %> <% end %> <% end %>

This then works as expected.

Moving to Ruby 1.9.3 and Rails 3.1.1

I've used rvm to install ruby 1.9.3-p0. Unfortunately, after installing, I get these errors:

yo:~ $ gem install rails
/Users/maryh/.rvm/rubies/ruby-1.9.3-p0/lib/ruby/1.9.1/yaml.rb:56:in `':
It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.

This did absolutely nothing and it's still annoying as heck.

To fix this, because it's annoying, I've tried this:

yo:~ $sudo port install libyaml
yo:~ $ rvm install ruby-1.9.3-p0 --with-libyaml=/opt/local
yo:~ $ gem install psych

That fixed things. Though, the --with-libyaml bit was ignored, so I could have dropped it and gotten the same result.

BUG! Just found that there's a bug between ruby 1.9.3 and passenger 3.0.9. The error I was getting is discussed here. The solution is to go back to ruby 1.9.2 for now.