obfuscurity / judy

Bespoke service for reviewing CFP submissions
http://obfuscurity.github.io/judy
Other
25 stars 6 forks source link

Abstracts queries fail without seeded data in Scores #1

Closed obfuscurity closed 10 years ago

obfuscurity commented 10 years ago

Because of the way Postgres handles negation with nulls (e.g. NOT IN), it's not possible to run a query like the following without a seeded entry in the Score table.

SELECT abstracts.*, speakers.full_name AS speaker, 
               speakers.email, events.name AS event_name
FROM abstracts, speakers, events, scores
WHERE ((abstracts.speaker_id = speakers.id)
    AND (abstracts.event_id = events.id)
    AND ((scores.abstract_id != abstracts.id)
        OR (scores.judge != 'jdixon')))
ORDER BY abstracts.id

Demonstration showing a successful query when at least one Score exists. Note that it works for all users regardless of whether they have a score recorded or not.

[20] pry(main)> Score.insert(:judge => 'jdixon', :count => 0, :abstract_id => 81)
=> 2
[21] pry(main)> Score.all
=> [#<Score @values={:id=>2, :judge=>"jdixon", :count=>0, :abstract_id=>81}>]
[22] pry(main)> Abstract.fetch_one_random_unscored_by_user('jdixon').id
=> 26
[23] pry(main)> Abstract.fetch_one_random_unscored_by_user('whilp').id
=> 53

Demonstration showing failed queries when no scores exist.

[26] pry(main)> Score.first.destroy
=> #<Score @values={:id=>2, :judge=>"jdixon", :count=>0, :abstract_id=>81}>
[27] pry(main)> Score.all
=> []
[28] pry(main)> Abstract.fetch_one_random_unscored_by_user('jdixon').id
=> nil
[29] pry(main)> Abstract.fetch_one_random_unscored_by_user('whilp').id
=> nil

One last time, proving that the simple existence of a Score is sufficient to workaround this issue.

[30] pry(main)> Score.insert(:judge => 'jdixon', :count => 0, :abstract_id => 81)
=> 3
[31] pry(main)> Score.all
=> [#<Score @values={:id=>3, :judge=>"jdixon", :count=>0, :abstract_id=>81}>]
[32] pry(main)> Abstract.fetch_one_random_unscored_by_user('jdixon').id
=> 4
[33] pry(main)> Abstract.fetch_one_random_unscored_by_user('whilp').id
=> 19
obfuscurity commented 10 years ago

I'd prefer to fix this somehow in the SQL, if possible. The alternative would be to handle the exclusion in application code by pulling Score.all separately and coalescing the results.