You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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: truebeginrequire"bundler/inline"rescueLoadError=>e
$stderr.puts"Bundler version 1.10 or later is required. Please update your Bundler"raiseeendgemfile(true)dosource"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"endrequire"active_record"require"minitest/autorun"require"logger"# Ensure backward compatibility with Minitest 4Minitest::Test=MiniTest::Unit::TestCaseunlessdefined?(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.definedocreate_table:posts,force: :truedo |t|
t.string:contentt.string:author_idendcreate_table:authors,id: :string,force: :truedo |t|
t.string:nameendendclassPost < ActiveRecord::Basebelongs_to:authorendclassAuthor < ActiveRecord::BaseendclassBugTest < Minitest::Testdeftest_relation_pluckauthor=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"))endend
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
The text was updated successfully, but these errors were encountered:
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.
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.
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 runruby test_pluck.rb
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 ofPost
, instead ofAuthor
. 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
to1 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
The text was updated successfully, but these errors were encountered: