Hello,
I am really pulling my hair out on this one and so would desperately appreciate any help. The application I am building has Schools and SchoolZones, both are in a HABTM relationship. On the School view there is a list of checkbox for each corresponding SchoolZone that School should belong to. When I submit, either for a Create and Update action I get the following error.
ActiveRecord::AssociationTypeMismatch in SchoolsController#update SchoolZone expected, got SchoolZone /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ associations/association_proxy.rb:148:in `raise_on_type_mismatch' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ associations/association_collection.rb:141:in `replace' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ associations/association_collection.rb:141:in `each' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ associations/association_collection.rb:141:in `replace' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ associations.rb:962:in `school_zones=' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ associations.rb:972:in `send' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ associations.rb:972:in `school_zone_ids=' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ base.rb:1675:in `send' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ base.rb:1675:in `attributes=' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ base.rb:1674:in `each' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ base.rb:1674:in `attributes=' /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.5/lib/active_record/ base.rb:1594:in `update_attributes' /var/www/html/BostonConnects/app/controllers/schools_controller.rb: 57:in `update' /usr/bin/mongrel_rails:16:in `load' /usr/bin/mongrel_rails:16
The really wierd thing is that this works on my local, which is a Windows XP machine. The error only shows when I deploy it to our Linux test environment. I posted the other code below in the hopes that it helps. Any insight would be appreciated at this point... Many thanks in advance. -- Chad
class School < ActiveRecord::Base # Relationships #has_and_belongs_to_many :users has_and_belongs_to_many :services has_and_belongs_to_many :school_zones has_many :students has_many :users
# End Relationships
# Properties attr_accessor :email_address_confirmation
def school_zone_names if @school_zones.nil? school_zones end
s = "" i = 0 for schoolzone in @school_zones s += i == 0 ? schoolzone.name : ", " + schoolzone.name i += 1 end @school_zone_names = s end
def principal_full_name @principal_full_name = " #{principal_first_name} #{principal_last_name}" end # End Properties
# Validators validates_presence_of :name, :address_one, :city, :state, :zipcode validates_confirmation_of :email_address, :if => Proc.new{ |u| !u.email_address.blank? } validates_format_of :zipcode, :with => /^\d{5}([-|\s]?\d{4})?$/ix, :if => Proc.new { |u| !u.zipcode.blank? } validates_format_of :email_address, :with => /^\S+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,4}) (\]?)$/ix, :if => Proc.new { |u| !u.email_address.blank? } validates_format_of :phone_one, :with => /^(\d{3}-?\d{3}-?\d{4})(\s[a-zA-Z0-9\s\.\-\#]{0,15})?$/ ix, :message => "is invalid. Must be in the xxx-xxx-xxxx format.", :if => Proc.new { |u| !u.phone_one.blank? } validates_format_of :phone_two, :with => /^(\d{3}-?\d{3}-?\d{4})(\s[a-zA-Z0-9\s\.\-\#]{0,15})?$/ ix, :message => "is invalid. Must be in the xxx-xxx-xxxx format.", :if => Proc.new { |u| !u.phone_two.blank? } validates_format_of :fax, :with => /^(\d{3}-?\d{3}-?\d{4})(\s[a-zA-Z0-9\s\.\-\#]{0,15})?$/ ix, :message => "is invalid. Must be in the xxx-xxx-xxxx format.", :if => Proc.new { |u| !u.fax.blank?} # End Validators
# Static Methods def School.find_id_and_name School.find(:all, :select => "schools.id, schools.name", :conditions => "schools.active = 1", :order => "schools.name") end
def School.search(search_term, show_inactive, page, sort_order) page_size = 50 if (search_term && search_term.empty? == false) School.paginate(:per_page => page_size, :page => page, :conditions => ['schools.active = ' + show_inactive + ' AND schools.name LIKE ?', "%#{search_term}%"], :order => sort_order) else School.paginate(:per_page => page_size, :page => page, :conditions => 'schools.active = ' + show_inactive, :order => sort_order) end end # End Methods
end
class SchoolZone < ActiveRecord::Base # Relationships has_and_belongs_to_many :schools # End Relationship
# Static Methods def SchoolZone.find_id_and_name() SchoolZone.find(:all, :select => "school_zones.id, school_zones.name", :conditions => "school_zones.active = 1", :order => "school_zones.name") end # End Static Methods end
class SchoolsController < ApplicationController helper :sort include SortHelper require "form_value" helper :search include SearchHelper
def index list render :action => 'list' end
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) verify :method => :post, :only => [ :create, :update ], :redirect_to => { :action => :list }
def list search = params[:search] sort_init('name', :table => 'schools') sort_update search_init @schools = School.search(search_term, show_inactive, params[:page], sort_clause) end
def new @school = School.new init_form_values() end
def create @school = School.new(params[:school]) @school.updated_by_id = session[:user_id].to_i init_form_values()
if @school.save flash[:notice] = 'The record for ' + @school.name + ' was successfully created.' redirect_to :action => 'list' else render :action => 'new' end end
def edit @school = School.find(params[:id]) init_form_values() end
def update @school = School.find(params[:id]) @school.updated_by_id = session[:user_id].to_i init_form_values()
if !params['school']['school_zone_ids'] @school.school_zones.clear end
if @school.update_attributes(params[:school]) flash[:notice] = 'The record for ' + @school.name + ' was successfully saved.' redirect_to :action => 'list' else render :action => 'edit' end end
private def init_form_values() @zones = SchoolZone.find_id_and_name() @states = FormValue.find_states() end end
School View: <%= error_messages_for 'school' %>
<!--[form:school]--> <table class="form"> <tr> <td class="label"><label for="school_name"><span class="req">*</
School name: </label></td>
<td><%= form.text_field :name, :class => "tb", :maxlength => "50" %></td> </tr>
<tr> <td class="label"><label for="school_principal_first_name">Principal First name: </label></td> <td><%= form.text_field :principal_first_name, :class => "tb", :maxlength => "50" %></td> </tr>
<tr> <td class="label"><label for="school_principal_last_name">Principal Last name: </label></td> <td><%= form.text_field :principal_last_name, :class => "tb", :maxlength => "50" %></td> </tr>
<tr> <td class="label"><label for="school_phone_one">Phone one: </label></
<td><%= form.text_field :phone_one, :class => "tb", :maxlength => "12" %></td> </tr>
<tr> <td class="label"><label for="school_phone_two">Phone two: </label></
<td><%= form.text_field :phone_two, :class => "tb", :maxlength => "12" %></td> </tr>
<tr> <td class="label"><label for="school_fax">Fax: </label></td> <td><%= form.text_field :fax, :class => "tb", :maxlength => "12" %></
</tr>
<tr> <td class="label"><label for="school_email_address">Email Address: </
</td>
<td><%= form.text_field :email_address, :class => "tb", :maxlength => "150" %></td> </tr>
<% if @school.new_record? %> <tr> <td class="label"><label for="school_address_confirmation">Re-type Email address: </label></td> <td><%= form.text_field :email_address_confirmation, :class => "tb", :maxlength => "150" %></td> </tr> <% end%>
<tr> <td class="label"><label for="school_website">Website: </label></td> <td><%= form.text_field :website, :class => "tb", :maxlength => "150" %></td> </tr>
<tr> <td class="label"><label for="school_school_zone">School zone: </
</td>
<td><% for school_zone in @zones %> <input class="cb" type="checkbox" id="school_zone_<%= school_zone.id.to_s %>" name="school[school_zone_ids]" value="<%= school_zone.id %>" <% if @school.school_zone_ids.include?(school_zone.id) %> checked="checked" <% end %> /> <label class="cb" for="school_zone_<%= school_zone.id.to_s %>"><%= school_zone.name %></label><br /> <% end %>
</td> </tr>
<tr> <td class="label"><label for="school_address_one"><span class="req">*</span> Address one: </label></td> <td><%= form.text_field :address_one, :class => "tb", :maxlength => "50" %></td> </tr>
<tr> <td class="label"><label for="school_address_two">Address two: </
</td>
<td><%= form.text_field :address_two, :class => "tb", :maxlength => "50" %></td> </tr>
<tr> <td class="label"><label for="school_city"><span class="req">*</
City: </label></td>
<td><%= form.text_field :city, :class => "tb", :maxlength => "50" %></td> </tr>
<tr> <td class="label"><label for="school_state"><span class="req">*</
State: </label></td>
<td><%= form.select(:state, @states.map{ |i| [i.label, i.value] }, {:prompt => true}, :class => "ddl" ) %></td> </tr>
<tr> <td class="label"><label for="school_zipcode"><span class="req">*</
Zipcode: </label></td>
<td><%= form.text_field :zipcode, :class => "tb", :maxlength => "10" %></td> </tr>
<tr> <td class="label">Support Team Meeting Times:</td> <td> <div class="label">Individual review</div> <%= form.text_field :support_meeting_notes, :class => "tb", :maxlength => "500" %> <div /> <% if @school.new_record? || @school.support_meeting_times.nil? %> <%= form.radio_button :support_meeting_times, 1, :class => "rb", :checked => true %> <% else %> <%= form.radio_button :support_meeting_times, 1, :class => "rb" %> <% end %> <label class="rb" for="school_support_meeting_times_1">NA</label> <%= form.radio_button :support_meeting_times, 2, :class => "rb" %> <label class="rb" for="school_support_meeting_times_2">Weekly</
<%= form.radio_button :support_meeting_times, 3, :class => "rb" %> <label class="rb" for="school_support_meeting_times_3">Bi-Weekly</
</td> </tr>
<tr> <td class="label"></td> <td style="padding-top: 5px;"> <div class="label">Whole class review</div> <%= form.text_field :class_meeting_notes, :class => "tb", :maxlength => "500" %> <div /> <% if @school.new_record? || @school.class_meeting_times.nil?%> <%= form.radio_button :class_meeting_times, 1, :class => "rb",:checked => true %> <% else %> <%= form.radio_button :class_meeting_times, 1, :class => "rb" %> <% end %> <label class="rb" for="school_class_meeting_times_1">NA</label> <%= form.radio_button :class_meeting_times, 2, :class => "rb" %> <label class="rb" for="school_class_meeting_times_2">Weekly</label> <%= form.radio_button :class_meeting_times, 3, :class => "rb" %> <label class="rb" for="school_class_meeting_times_3">Bi-Weekly</
</td> </tr>
<tr> <td class="label"><label for="school_notes">Notes: </label></td> <td><%= form.text_area :notes, :style=>"width: 98%; height: 50px;", :class => "tb", :maxlength => "1000" %></td> </tr>
<tr> <td class="label"><span class="req">*</span> Status: </td> <td><%= form.radio_button :active, 'false', :class => "rb" %> <label class="rb" for="school_active_false">Inactive</label> <% if @school.new_record?%> <%= form.radio_button :active, 'true', :checked => true, :class => "rb" %> <% else %> <%= form.radio_button :active, 'true', :class => "rb" %> <% end %> <label class="rb" for="school_active_true">Active</label> </td> </tr> </table>
<%= form.hidden_field :created_on %> <%= form.hidden_field :updated_on %> <%= form.hidden_field :lock_version %> <!--[eoform:school]-->
DataBase Schema: create_table "school_zones", :force => true do |t| t.column "name", :string, :limit => 150, :default => "", :null => false t.column "active", :integer, :default => 1, :null => false end
create_table "school_zones_schools", :id => false, :force => true do
t>
t.column "school_id", :integer, :null => false t.column "school_zone_id", :integer, :null => false end
create_table "schools", :force => true do |t| t.column "name", :string, :limit => 150, :default => "", :null => false t.column "website", :string, :limit => 150 t.column "principal_first_name", :string, :limit => 50 t.column "principal_last_name", :string, :limit => 50 t.column "email_address", :string, :limit => 150 t.column "phone_one", :string, :limit => 20 t.column "phone_two", :string, :limit => 20 t.column "fax", :string, :limit => 20 t.column "school_zone", :integer t.column "address_one", :string, :limit => 50, :default => "", :null => false t.column "address_two", :string, :limit => 50 t.column "city", :string, :limit => 50, :default => "", :null => false t.column "state", :string, :limit => 2, :default => "", :null => false t.column "zipcode", :string, :limit => 10, :default => "", :null => false t.column "support_meeting_notes", :string, :limit => 500 t.column "support_meeting_times", :integer, :default => 1, :null => false t.column "class_meeting_notes", :string, :limit => 500 t.column "class_meeting_times", :integer, :default => 1, :null => false t.column "notes", :string, :limit => 1000 t.column "active", :boolean, :default => true, :null => false t.column "updated_by_id", :integer, :null => false t.column "created_on", :datetime, :null => false t.column "updated_on", :datetime, :null => false t.column "lock_version", :integer, :default => 1, :null => false end