I've added a link in the pull request you mention so that people finding this in Github's issues view can track this.
El sábado, 20 de abril de 2019, 7:27:55 (UTC+2), Stan Lo escribió: > > From the examples in documents, it looks like AR#pluck is mainly for > retrieving columns from the same table. Like > Post.pluck(:author_id) > > But we can also find some people using pluck for joined tables' columns, > like > Post.joins(:author).pluck("author.name", :title) > > And normally this works fine, except for cases like > https://github.com/rails/rails/issues/36042. > > class Post < ActiveRecord::Base > enum status: { > a: "a", > b: "b", > c: "c" > } > has_many :comments > end > > class Comment < ActiveRecord::Base > enum status: { > red: "red", > green: "green", > blue: "blue" > } > belongs_to :post > end > > class BugTest < Minitest::Test > def test_association_stuff > post = Post.create!(status: "a") > post.comments << Comment.create!(status: "blue", not_enum: "blue") > > expected = [["a", "blue", "blue"]] > actual = Post.includes(:comments).pluck(:status, "comments.status", > "comments.not_enum") > assert_equal expected, actual > end > end > > > After digging into the issue, I think plucking joined tables' columns is > kind of a misuse of pluck. Here's the source code of pluck > > def pluck(*column_names) > if loaded? && (column_names.map(&:to_s) - @klass.attribute_names - > @klass.attribute_aliases.keys).empty? > return records.pluck(*column_names) > end > > if has_include?(column_names.first) > relation = apply_join_dependency > relation.pluck(*column_names) > else > klass.disallow_raw_sql!(column_names) > relation = spawn > relation.select_values = column_names > result = skip_query_cache_if_necessary { > klass.connection.select_all(relation.arel, nil) } > result.cast_values(klass.attribute_types) > end > end > > > And the cause of the issue above is > > result.cast_values(klass.attribute_types) > > Pluck seems assume it'll only be used for the same table, so it uses the > original class' attribute types to cast column values (in this case, the > Post's attribute types). Hence when the joined table's columns need > different casting methods (like different enum definitions), Rails may get > confused. (For generic types like integer, string that won't be a problem > though, that's why most people don't have issue). And for our issue > example, Rails tried to use Post's status type definition to cast Comment's > status type, and as expected it failed. > > So my question is, should we have a full support on this behavior? Which > means we'd need to be able to cast types for every tables envolved. And > this won't be a small change since we now need to get all tables' type > definitions. Or we should consider this as a misuse and not receommending > using it (or even deprecate it). > > > > > > > -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscr...@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at https://groups.google.com/group/rubyonrails-core. For more options, visit https://groups.google.com/d/optout.