It appears that find_or_create_by_xxx is attempting type conversion where a simple create(...) does not. Bug? Before going further, here''s the schema and the model: create_table "weather_stations", :force => true do |t| t.string "callsign" t.decimal "lat", :precision => 9, :scale => 6 t.decimal "lng", :precision => 9, :scale => 6 t.decimal "elevation_m", :precision => 5, :scale => 1 end class WeatherStation < ActiveRecord::Base validates_presence_of :callsign, :lat, :lng validates_uniqueness_of :callsign, :case_sensitive => false acts_as_mappable ... end [Note the "validates_uniqueness_of :callsign, :case_sensitive => false" -- that comes into play here.] ** Assume ''specs'' is a hash whose :callsign is a string:>> specs=> {:callsign=>"0N6", :lat=>39.0128889, :lng=>-75.5339722, :elevation_m=>15.0}>> specs[:callsign].class=> String ** The call to find_or_create_by_callsign fails -- note that id comes back nil and the other fields are not filled in:>> w = WeatherStation.find_or_create_by_callsign(specs[:callsign], :lat => specs[:lat], :lng => specs[:lng])=> #<WeatherStation id: nil, callsign: "0N6", domain: nil, created_at: nil, updated_at: nil, lat: nil, lng: nil, elevation_m: nil> ** The generated SQL shows a rollback: WeatherStation Load (22.2ms) SELECT * FROM `weather_stations` WHERE (`weather_stations`.`callsign` = ''0N6'') LIMIT 1 SQL (0.4ms) BEGIN WeatherStation Load (230.6ms) SELECT `weather_stations`.id FROM `weather_stations` WHERE (LOWER(`weather_stations`.`callsign`) = BINARY ''0n6'') LIMIT 1 SQL (1.0ms) ROLLBACK ** Using a simple .create() instead works:>> x = WeatherStation.create(:callsign => specs[:callsign], :lat => specs[:lat], :lng => specs[:lng])=> #<WeatherStation id: 30774, callsign: "0N6", domain: nil, created_at: "2010-05-16 06:38:22", updated_at: "2010-05-16 06:38:22", lat: #<BigDecimal:8db79b0,''0.390128889E2'',12(16)>, lng: #<BigDecimal:8db7828,''-0.755339722E2'',12(16)>, elevation_m: nil> ** ...but looking at the SQL shows that it does the same check for uniqueness before inserting the row. Since the record isn''t in the table, it''s okay that it fails: SQL (70.0ms) BEGIN WeatherStation Load (365.4ms) SELECT `weather_stations`.id FROM `weather_stations` WHERE (LOWER(`weather_stations`.`callsign`) = BINARY ''0n6'') LIMIT 1 WeatherStation Create (2.0ms) INSERT INTO `weather_stations` (`callsign`, `domain`, `created_at`, `updated_at`, `lat`, `lng`, `elevation_m`) VALUES(''0N6'', NULL, ''2010-05-16 06:38:22'', ''2010-05-16 06:38:22'', 39.0128889, -75.5339722, NULL) SQL (3.3ms) COMMIT I don''t understand enough about SQL''s "BINARY ''0n6''" -- is that the source of the trouble? Or is my validation bogus? Why is find_or_create_by_callsign() failing? TIA. - ff -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung
2010-May-16 10:10 UTC
Re: find_or_create_xxx behaving differently than create
On May 16, 8:56 am, Fearless Fool <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> I don''t understand enough about SQL''s "BINARY ''0n6''" -- is that the > source of the trouble? Or is my validation bogus? Why is > find_or_create_by_callsign() failing? >I think it''s far more likely that it''s the nil attributes you noted that are the problem - they would certainly prevent the record from being saved. It appears that find_or_create_by doesn''t quite work the way you expected it to - the code and unit tests suggests that you should be doing WeatherStation.find_or_create_by_callsign(:callsign => specs[:callsign], :lat => specs[:lat], :lng => specs[:lng]) There is an another example in the docs of the usage you were attempting though, looks like it is just wrong/misleading. Fred> TIA. > > - ff > -- > Posted viahttp://www.ruby-forum.com/. > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. > For more options, visit this group athttp://groups.google.com/group/rubyonrails-talk?hl=en.-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Fearless Fool
2010-May-16 15:27 UTC
Re: find_or_create_xxx behaving differently than create
Frederick Cheung wrote:> ... > It appears that find_or_create_by doesn''t quite work the way you > expected it to - the code and unit tests suggests that you should be > doing > > WeatherStation.find_or_create_by_callsign(:callsign => > specs[:callsign], :lat => specs[:lat], :lng => specs[:lng])You are correct -- that works as expected.> There is an another example in the docs of the usage you were > attempting though, looks like it is just wrong/misleading.Correct again! The line in the doc is: # No ''Summer'' tag exists Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => "Summer") which passes "Summer" rather than :name => "Summer". Sigh. A guy I used to work with told me that there is only one "authoritative documentation", and that''s the source code itself. Evidently, Rails subscribes to this philosophy as well. -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Frederick Cheung
2010-May-16 15:58 UTC
Re: find_or_create_xxx behaving differently than create
On 16 May, 17:27, Fearless Fool <li...-fsXkhYbjdPsEEoCn2XhGlw@public.gmane.org> wrote:> Frederick Cheung wrote: > > ...> > There is an another example in the docs of the usage you were > > attempting though, looks like it is just wrong/misleading. > > Correct again! The line in the doc is: > > # No ''Summer'' tag exists > Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name => > "Summer") >Actually that usage is correct too. The misleading example is actuall demonstrating a different point.> which passes "Summer" rather than :name => "Summer". > > Sigh. A guy I used to work with told me that there is only one > "authoritative documentation", and that''s the source code itself. > Evidently, Rails subscribes to this philosophy as well.A fair amount of effort has gone into the rails documentation of late. Like the rest of rails it only gets better if people contribute> -- > Posted viahttp://www.ruby-forum.com/. > > -- > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. > To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org > To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. > For more options, visit this group athttp://groups.google.com/group/rubyonrails-talk?hl=en.-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Fearless Fool
2010-May-16 16:36 UTC
Re: find_or_create_xxx behaving differently than create
Frederick Cheung wrote:> A fair amount of effort has gone into the rails documentation of late. > Like the rest of rails it only gets better if people contributeAgreed. But, as evidenced by my sometimes boneheaded questions in this forum, Rails would be in serious trouble if I were a contributor! :) (At least for now...) -- Posted via http://www.ruby-forum.com/. -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.