Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pluck relations is casting values for the wrong model #32856

Closed
manu-d opened this issue May 9, 2018 · 2 comments
Closed

Pluck relations is casting values for the wrong model #32856

manu-d opened this issue May 9, 2018 · 2 comments

Comments

@manu-d
Copy link

manu-d commented May 9, 2018

Steps to reproduce

When plucking an associated model attributes, Active record is casting values based on the original model attributes types, instead of the associated one

Test example

Simply save this file test_pluck.rb, and run ruby test_pluck.rb

# frozen_string_literal: true

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"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "activerecord", "5.2.0"
  gem "sqlite3"
end

require "active_record"
require "minitest/autorun"
require "logger"

# Ensure backward compatibility with Minitest 4
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)

# 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|
    t.string :content
    t.string :author_id
  end

  create_table :authors, id: :string, force: :true do |t|
    t.string :name
  end
end

class Post < ActiveRecord::Base
  belongs_to :author
end

class Author < ActiveRecord::Base
end

class BugTest < Minitest::Test
  def test_relation_pluck
    author = Author.create!(id: "Author 1", name: "Maupassant")
    post = Post.create!(content: "Horla", author: author)
    relation = Post.includes(:author)
    assert_equal [author.name], relation.pluck(Arel.sql("authors.name"))
    assert_equal [author.id], relation.pluck(Arel.sql("authors.id"))
  end
end

Actual behavior

We can see that the first test works. However, the second one fails.
It seems that here, for klass.attributes_types, we are sending the attributes types of Post, instead of Author. Since Post has an Integer id, the Author id will be cast to an integer.
Therefore, 'Author 1'.to_i will return 0.
(If you change the id Author 1 to 1 Author, '1 Author'.to_i = 1, so it will return 1)
SQL request is correct, and returning the correct value. The casting to int is breaking it.

System configuration

Rails version: 5.2.0

Ruby version: 2.4.1

@manu-d
Copy link
Author

manu-d commented May 14, 2018

(Test case fails with any active record version > 4)

ricardotk002 added a commit to ricardotk002/rails that referenced this issue May 17, 2018
The bug rails#32856 is caused because after executing the select statement,
the result relationship losses the table references. For instance, if
our query was `authors.id`, it becomes just `id`. Then, when we cast
the values, for the `id` case ActiveRecord will look for the type for
that column in `klass.cast_values` and will use the wrong type.
@rails-bot rails-bot bot added the stale label Aug 12, 2018
@rails-bot
Copy link

rails-bot bot commented Aug 12, 2018

This issue has been automatically marked as stale because it has not been commented on for at least three months.
The resources of the Rails team are limited, and so we are asking for your help.
If you can still reproduce this error on the 5-2-stable branch or on master, please reply with all of the information you have about it in order to keep the issue open.
Thank you for all your contributions.

@rails-bot rails-bot bot closed this as completed Aug 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants