Skip to content
This repository has been archived by the owner on Mar 30, 2022. It is now read-only.

Rails 4.2.4 - Mixing attribute values #400

Open
brunobrgs opened this issue Sep 14, 2015 · 4 comments
Open

Rails 4.2.4 - Mixing attribute values #400

brunobrgs opened this issue Sep 14, 2015 · 4 comments

Comments

@brunobrgs
Copy link

First of all, the problem starts with a duplication on sql condition on rails 4.2, when i call the same scope twice. Following this issue rails/rails#21626

When i updated my rails to 4.2.4, the sql generated is mixing the attribute values, like script below shows:

begin
  require 'bundler/inline'
rescue LoadError => e
  $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
  raise e
end

gemfile(true) do
  source 'https://rubygems.org'
  gem 'rails', '4.2.4', require: 'active_record'
  gem 'sqlite3'
  gem 'arel'
  gem 'squeel', '1.2.3'
end

require 'active_record'
require 'minitest/autorun'
require 'logger'

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :posts, force: true  do |t|
  end

  create_table :comments, force: true  do |t|
    t.integer :post_id
    t.string :classification
    t.string :nature
    t.boolean :active
  end
end

class Post < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post

  scope :active, -> value = true { where(active: value) }
  scope :by_classification, -> value { where(classification: value) }
  scope :by_nature, -> value { where(nature: value) }
  scope :mix, -> { active.by_classification('A').by_nature('B') }
end

class BugTest < Minitest::Test
  def test_association_stuff
    post = Post.create!
    post.comments << Comment.create!

    #1 Call
    sql1 = "SELECT \"comments\".* FROM \"comments\" WHERE \"comments\".\"active\" = 't' AND \"comments\".\"classification\" = 'A' AND \"comments\".\"nature\" = 'B'"
    assert_equal sql1, Comment.mix.to_sql

    #2 Calls
    sql2 = "SELECT \"comments\".* FROM \"comments\" WHERE \"comments\".\"active\" = 't' AND \"comments\".\"active\" = 'A' AND \"comments\".\"classification\" = 'B' AND \"comments\".\"classification\" = 't' AND \"comments\".\"nature\" = 'A' AND \"comments\".\"nature\" = 'B'"
    assert_equal sql2, Comment.mix.mix.to_sql
  end
end
@fschwahn
Copy link

fschwahn commented Nov 6, 2015

I just spent half an hour creating almost the exact same repro-case - I should have checked here first, but I actually thought it was an issue in activerecord itself, as I was using no squeel behavior, I was just including the gem.

I really like squeel, but I have run into problems with it time and time again. This is not at all the fault of squeel, as the reasons are mainly that activerecord internals can change even in minor versions enough to break squeel (in this case going from 4.2.2 to 4.2.3). Which is also not the fault of the rails developers, these are internals after all which can change at any time. Just starting to realize that heavily patching rails internals is a game you'll eventually lose.

In newer projects I've started to just use arel directly if I need anything rails doesn't provide - the syntax is not even close to squeel in terms of verbosity and readability, but it seems to survive even major rails updates without problems.

@konk303
Copy link

konk303 commented Jan 7, 2016

I was trying to upgrade rails from 4.1 to 4.2 and came to this problem.
I tried versions from 4.2.5 down to 4.2.0 and it's all there, so I assume this is introduced with rails 4.2.0, and happens ever since.

# I'm using mysql 5.6

# squeel 1.2.3 with rails 4.1.14
[1] pry(main)> User.where(id: 1).where(email: '[email protected]').where(id: 1).to_sql
=> "SELECT `users`.* FROM `users`  WHERE `users`.`id` = 1 AND `users`.`email` = '[email protected]'"

# squeel 1.2.3 with rails 4.2.(0-5)
[1] pry(main)> User.where(id: 1).where(email: '[email protected]').where(id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 AND `users`.`id` = '[email protected]' AND `users`.`email` = 1"

rails/rails#21626 is surely happening, and that spec change might have broken squeel.

This one's preventing me from upgrading rails to 4.2 ...

@Skulli
Copy link

Skulli commented Mar 22, 2016

Having the same problem on several queries where the attributes are getting mixed.

@Skulli
Copy link

Skulli commented Nov 17, 2016

@farrspace thanks for the fix, thats working for me 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants