开发者

Rails with autocomplete association blows if different cased input is given

It is a Rails 3.0.9 application.

Following is the place model with its belongs_to asso开发者_开发问答ciation with city and address which both have has_many :places association. The place model uses virtual attributes and the view implements jQuery auto_completion. Its implemented as in Railscasts episode 102. In the cast, it shows single category model. But in my implementation, the place model has 2 models city and address

I've used the virtual attributes to accomplish the autocompletion and if the record doesn't exists, it has to create it.

class Place < ActiveRecord::Base
  belongs_to :city
  belongs_to :address

  def city_name
    city.name if city
  end

  def city_name=(name)
    self.city = City.find_or_create_by_name(name) unless name.blank?
  end

  def address_name
    address.name if address
  end

  def address_name=(name)
    self.address = Address.find_or_create_by_name(name) unless name.blank?
  end
end

And this is the city model. And the address model is also the same with the class name Address.

class City < ActiveRecord::Base
  has_many :events
  has_many :places
  validates :name, :presence => true,
            :length => {:maximum => 30, :message => "Address can't be longer than 30 chars."}, 
            :uniqueness => {:message => "has already been taken", :case_sensitive => false}

end
  • While I try to create a place with with the city_name and address_name with the value thats already stored in database, it works fine.
  • When I try to add with non-existing/new city_name and address_name, it works.
  • When any or both existing records and I try to put with different case, e.g. address Thamel exists but I put thamel (lowered case), it blows up with the following error report:

This is the backtrace from the log:

Processing by PlacesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"5igpohqctBnRUWjPYu6GnXo6btx8SDe/PJRgF2eTG2A=", "place"=>{"name"=>"aaaa", "image_cache"=>"", "category_id"=>"1", "sub_category_id"=>"2", "hot"=>"0", "featured_till_date"=>"", "opens"=>"11 am", "street"=>"", "address_name"=>"thamel", "city_name"=>"pokhara", "description"=>"sdfdsf"}, "commit"=>"Post my Place"}
  Address Load (0.3ms)  SELECT "addresses".* FROM "addresses" WHERE "addresses"."name" = 'thamel' LIMIT 1
  SQL (0.3ms)  SELECT 1 FROM "addresses" WHERE (LOWER("addresses"."name") = LOWER('thamel')) LIMIT 1
  City Load (0.2ms)  SELECT "cities".* FROM "cities" WHERE "cities"."name" = 'pokhara' LIMIT 1
  SQL (0.3ms)  SELECT 1 FROM "cities" WHERE (LOWER("cities"."name") = LOWER('pokhara')) LIMIT 1
  User Load (0.9ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 11 ORDER BY created_at DESC LIMIT 1
  CACHE (0.0ms)  SELECT "addresses".* FROM "addresses" WHERE "addresses"."name" = 'thamel' LIMIT 1
  CACHE (0.0ms)  SELECT 1 FROM "addresses" WHERE (LOWER("addresses"."name") = LOWER('thamel')) LIMIT 1
  CACHE (0.0ms)  SELECT "cities".* FROM "cities" WHERE "cities"."name" = 'pokhara' LIMIT 1
  CACHE (0.0ms)  SELECT 1 FROM "cities" WHERE (LOWER("cities"."name") = LOWER('pokhara')) LIMIT 1
  SQL (0.3ms)  SELECT 1 FROM "places" WHERE (LOWER("places"."name") = LOWER('aaaa')) LIMIT 1
  CACHE (0.0ms)  SELECT 1 FROM "cities" WHERE (LOWER("cities"."name") = LOWER('pokhara')) LIMIT 1
  CACHE (0.0ms)  SELECT 1 FROM "addresses" WHERE (LOWER("addresses"."name") = LOWER('thamel')) LIMIT 1
  AREL (0.5ms)  INSERT INTO "places" ("user_id", "name", "image", "category_id", "sub_category_id", "opens", "street", "city_id", "address_id", "description", "created_at", "updated_at") VALUES (11, 'Aaaa', NULL, 1, 2, '11 am', '', NULL, NULL, 'sdfdsf', '2011-07-31 15:00:25.182849', '2011-07-31 15:00:25.182849')
SQLite3::ConstraintException: places.city_id may not be NULL: INSERT INTO "places" ("user_id", "name", "image", "category_id", "sub_category_id", "opens", "street", "city_id", "address_id", "description", "created_at", "updated_at") VALUES (11, 'Aaaa', NULL, 1, 2, '11 am', '', NULL, NULL, 'sdfdsf', '2011-07-31 15:00:25.182849', '2011-07-31 15:00:25.182849')
Completed 500 Internal Server Error in 28625ms

ActiveRecord::StatementInvalid (SQLite3::ConstraintException: places.city_id may not be NULL: INSERT INTO "places" ("user_id", "name", "image", "category_id", "sub_category_id", "opens", "street", "city_id", "address_id", "description", "created_at", "updated_at") VALUES (11, 'Aaaa', NULL, 1, 2, '11 am', '', NULL, NULL, 'sdfdsf', '2011-07-31 15:00:25.182849', '2011-07-31 15:00:25.182849')):
  app/controllers/places_controller.rb:39:in `create' 

Its so weird. Any idea why its not behaving as expected when I try to create a place with city_name and address_name that doesn't exist?


Try it like this:

class Place < ActiveRecord::Base
  belongs_to :city
  belongs_to :address

  def city_name
    city.name if city
  end

  def city_name=(name)
    self.city_id = City.find_or_create_by_name(name).id unless name.blank?
  end

  def address_name
    address.name if address
  end

  def address_name=(name)
    self.address_id = Address.find_or_create_by_name(name).id unless name.blank?
  end
end


Actually the problem was with the sqlite3 db. I changed the db and the adapter to mysql2 and now the same code works.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜