{"action":"closed","number":30076,"pull_request":{"url":"https://api.github.com/repos/rails/rails/pulls/30076","id":134214330,"html_url":"https://github.com/rails/rails/pull/30076","diff_url":"https://github.com/rails/rails/pull/30076.diff","patch_url":"https://github.com/rails/rails/pull/30076.patch","issue_url":"https://api.github.com/repos/rails/rails/issues/30076","number":30076,"state":"closed","locked":false,"title":"fix preloading polymorphic source on multi-level has_many through","user":{"login":"CicholGricenchos","id":6355587,"avatar_url":"https://avatars2.githubusercontent.com/u/6355587?v=4","gravatar_id":"","url":"https://api.github.com/users/CicholGricenchos","html_url":"https://github.com/CicholGricenchos","followers_url":"https://api.github.com/users/CicholGricenchos/followers","following_url":"https://api.github.com/users/CicholGricenchos/following{/other_user}","gists_url":"https://api.github.com/users/CicholGricenchos/gists{/gist_id}","starred_url":"https://api.github.com/users/CicholGricenchos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CicholGricenchos/subscriptions","organizations_url":"https://api.github.com/users/CicholGricenchos/orgs","repos_url":"https://api.github.com/users/CicholGricenchos/repos","events_url":"https://api.github.com/users/CicholGricenchos/events{/privacy}","received_events_url":"https://api.github.com/users/CicholGricenchos/received_events","type":"User","site_admin":false},"body":"### Summary\r\n\r\nPreloading multi-level has_many through association, is currently discarding source_type option. \r\n\r\nReproduction:\r\n```ruby\r\nbegin\r\n  require \"bundler/inline\"\r\nrescue LoadError => e\r\n  $stderr.puts \"Bundler version 1.10 or later is required. Please update your Bundler\"\r\n  raise e\r\nend\r\n\r\ngemfile(true) do\r\n  source \"https://rubygems.org\"\r\n  gem \"rails\", github: \"rails/rails\"\r\n  gem \"arel\", github: \"rails/arel\"\r\n  gem \"sqlite3\"\r\nend\r\n\r\nrequire \"active_record\"\r\nrequire \"minitest/autorun\"\r\nrequire \"logger\"\r\n\r\n# This connection will do for database-independent bug reports.\r\nActiveRecord::Base.establish_connection(adapter: \"sqlite3\", database: \":memory:\")\r\nActiveRecord::Base.logger = Logger.new(STDOUT)\r\n\r\nActiveRecord::Schema.define do\r\n  create_table :hotels, force: true do |t|\r\n  end\r\n  create_table :departments, force: true do |t|\r\n    t.integer :hotel_id\r\n  end\r\n  create_table :cake_designers, force: true do |t|\r\n  end\r\n  create_table :drink_designers, force: true do |t|\r\n  end\r\n  create_table :chefs, force: true do |t|\r\n    t.integer :employable_id\r\n    t.string :employable_type\r\n    t.integer :department_id\r\n    t.string :employable_list_type\r\n    t.integer :employable_list_id\r\n  end\r\nend\r\n\r\nclass Hotel < ActiveRecord::Base\r\n  has_many :departments\r\n  has_many :chefs, through: :departments\r\n  has_many :cake_designers, source_type: \"CakeDesigner\", source: :employable, through: :chefs\r\n  has_many :drink_designers, source_type: \"DrinkDesigner\", source: :employable, through: :chefs\r\nend\r\n\r\nclass Department < ActiveRecord::Base\r\n  has_many :chefs\r\n  belongs_to :hotel\r\nend\r\n\r\nclass Chef < ActiveRecord::Base\r\n  belongs_to :employable, polymorphic: true\r\n  has_many :recipes\r\nend\r\n\r\nclass CakeDesigner < ActiveRecord::Base\r\n  has_one :chef, as: :employable\r\nend\r\n\r\nclass DrinkDesigner < ActiveRecord::Base\r\n  has_one :chef, as: :employable\r\nend\r\n\r\nclass BugTest < Minitest::Test\r\n  def test_preloading_polymorphic_source_on_two_level_has_many_through\r\n    hotel = Hotel.create!\r\n    department = hotel.departments.create!\r\n    cake_designer = CakeDesigner.create!\r\n    department.chefs.create!(employable: cake_designer)\r\n    department.chefs.create!(employable: DrinkDesigner.create!)\r\n\r\n    found_cake_designers = Hotel.preload(:cake_designers).find(hotel.id).cake_designers\r\n\r\n    assert_equal 1, found_cake_designers.size\r\n    assert_equal cake_designer, found_cake_designers.first\r\n  end\r\nend\r\n```\r\n\r\nAs the reproduction showed, the `hotel` with cake_designers preloaded is giving wrong result when calling `cake_designers` on it. The drink_designer is also returned in the collection.\r\n\r\nI found this caused by a parameter `preload_scope` being lost between two preload recursions.\r\n\r\nBelow is an example to describe the problem:\r\n\r\n```\r\nA -> B -> C -> P\r\nA has_many C through B\r\nA has_many P through C with source_type xxx\r\n\r\n   A querying P\r\n=  A querying P(reflection_scope_1) through C(through_scope_1)\r\n=  A querying P through\r\n        querying C(reflection_scope_2) through B(through_scope_2)\r\n```\r\nThe `through_scope_1` is the source_type constraint, which should be applied to C.\r\nThe `through_scope_1` is passed to the next level as `preload_scope`, and `reflection_scope_2` should merge `preload_scope` to yield right answer. However the `preload_scope` parameter is currently used nowhere.\r\n\r\nFor has_many through more than two levels, the patch should work correctly as well.\r\n\r\nAny advice is welcome.","created_at":"2017-08-04T17:26:37Z","updated_at":"2017-11-05T22:13:54Z","closed_at":"2017-11-05T22:13:54Z","merged_at":null,"merge_commit_sha":"c97117012d72b6bf5b883dc23c2fad593a3f092c","assignee":{"login":"pixeltrix","id":6321,"avatar_url":"https://avatars0.githubusercontent.com/u/6321?v=4","gravatar_id":"","url":"https://api.github.com/users/pixeltrix","html_url":"https://github.com/pixeltrix","followers_url":"https://api.github.com/users/pixeltrix/followers","following_url":"https://api.github.com/users/pixeltrix/following{/other_user}","gists_url":"https://api.github.com/users/pixeltrix/gists{/gist_id}","starred_url":"https://api.github.com/users/pixeltrix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pixeltrix/subscriptions","organizations_url":"https://api.github.com/users/pixeltrix/orgs","repos_url":"https://api.github.com/users/pixeltrix/repos","events_url":"https://api.github.com/users/pixeltrix/events{/privacy}","received_events_url":"https://api.github.com/users/pixeltrix/received_events","type":"User","site_admin":false},"assignees":[{"login":"pixeltrix","id":6321,"avatar_url":"https://avatars0.githubusercontent.com/u/6321?v=4","gravatar_id":"","url":"https://api.github.com/users/pixeltrix","html_url":"https://github.com/pixeltrix","followers_url":"https://api.github.com/users/pixeltrix/followers","following_url":"https://api.github.com/users/pixeltrix/following{/other_user}","gists_url":"https://api.github.com/users/pixeltrix/gists{/gist_id}","starred_url":"https://api.github.com/users/pixeltrix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pixeltrix/subscriptions","organizations_url":"https://api.github.com/users/pixeltrix/orgs","repos_url":"https://api.github.com/users/pixeltrix/repos","events_url":"https://api.github.com/users/pixeltrix/events{/privacy}","received_events_url":"https://api.github.com/users/pixeltrix/received_events","type":"User","site_admin":false}],"requested_reviewers":[{"login":"kamipo","id":12642,"avatar_url":"https://avatars0.githubusercontent.com/u/12642?v=4","gravatar_id":"","url":"https://api.github.com/users/kamipo","html_url":"https://github.com/kamipo","followers_url":"https://api.github.com/users/kamipo/followers","following_url":"https://api.github.com/users/kamipo/following{/other_user}","gists_url":"https://api.github.com/users/kamipo/gists{/gist_id}","starred_url":"https://api.github.com/users/kamipo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kamipo/subscriptions","organizations_url":"https://api.github.com/users/kamipo/orgs","repos_url":"https://api.github.com/users/kamipo/repos","events_url":"https://api.github.com/users/kamipo/events{/privacy}","received_events_url":"https://api.github.com/users/kamipo/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/rails/rails/pulls/30076/commits","review_comments_url":"https://api.github.com/repos/rails/rails/pulls/30076/comments","review_comment_url":"https://api.github.com/repos/rails/rails/pulls/comments{/number}","comments_url":"https://api.github.com/repos/rails/rails/issues/30076/comments","statuses_url":"https://api.github.com/repos/rails/rails/statuses/5528cf169e55033b3da32ca1c826ad8c0e47510a","head":{"label":"CicholGricenchos:bugfix","ref":"bugfix","sha":"5528cf169e55033b3da32ca1c826ad8c0e47510a","user":{"login":"CicholGricenchos","id":6355587,"avatar_url":"https://avatars2.githubusercontent.com/u/6355587?v=4","gravatar_id":"","url":"https://api.github.com/users/CicholGricenchos","html_url":"https://github.com/CicholGricenchos","followers_url":"https://api.github.com/users/CicholGricenchos/followers","following_url":"https://api.github.com/users/CicholGricenchos/following{/other_user}","gists_url":"https://api.github.com/users/CicholGricenchos/gists{/gist_id}","starred_url":"https://api.github.com/users/CicholGricenchos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CicholGricenchos/subscriptions","organizations_url":"https://api.github.com/users/CicholGricenchos/orgs","repos_url":"https://api.github.com/users/CicholGricenchos/repos","events_url":"https://api.github.com/users/CicholGricenchos/events{/privacy}","received_events_url":"https://api.github.com/users/CicholGricenchos/received_events","type":"User","site_admin":false},"repo":{"id":99348830,"name":"rails","full_name":"CicholGricenchos/rails","owner":{"login":"CicholGricenchos","id":6355587,"avatar_url":"https://avatars2.githubusercontent.com/u/6355587?v=4","gravatar_id":"","url":"https://api.github.com/users/CicholGricenchos","html_url":"https://github.com/CicholGricenchos","followers_url":"https://api.github.com/users/CicholGricenchos/followers","following_url":"https://api.github.com/users/CicholGricenchos/following{/other_user}","gists_url":"https://api.github.com/users/CicholGricenchos/gists{/gist_id}","starred_url":"https://api.github.com/users/CicholGricenchos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CicholGricenchos/subscriptions","organizations_url":"https://api.github.com/users/CicholGricenchos/orgs","repos_url":"https://api.github.com/users/CicholGricenchos/repos","events_url":"https://api.github.com/users/CicholGricenchos/events{/privacy}","received_events_url":"https://api.github.com/users/CicholGricenchos/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/CicholGricenchos/rails","description":"Ruby on Rails","fork":true,"url":"https://api.github.com/repos/CicholGricenchos/rails","forks_url":"https://api.github.com/repos/CicholGricenchos/rails/forks","keys_url":"https://api.github.com/repos/CicholGricenchos/rails/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CicholGricenchos/rails/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CicholGricenchos/rails/teams","hooks_url":"https://api.github.com/repos/CicholGricenchos/rails/hooks","issue_events_url":"https://api.github.com/repos/CicholGricenchos/rails/issues/events{/number}","events_url":"https://api.github.com/repos/CicholGricenchos/rails/events","assignees_url":"https://api.github.com/repos/CicholGricenchos/rails/assignees{/user}","branches_url":"https://api.github.com/repos/CicholGricenchos/rails/branches{/branch}","tags_url":"https://api.github.com/repos/CicholGricenchos/rails/tags","blobs_url":"https://api.github.com/repos/CicholGricenchos/rails/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CicholGricenchos/rails/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CicholGricenchos/rails/git/refs{/sha}","trees_url":"https://api.github.com/repos/CicholGricenchos/rails/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CicholGricenchos/rails/statuses/{sha}","languages_url":"https://api.github.com/repos/CicholGricenchos/rails/languages","stargazers_url":"https://api.github.com/repos/CicholGricenchos/rails/stargazers","contributors_url":"https://api.github.com/repos/CicholGricenchos/rails/contributors","subscribers_url":"https://api.github.com/repos/CicholGricenchos/rails/subscribers","subscription_url":"https://api.github.com/repos/CicholGricenchos/rails/subscription","commits_url":"https://api.github.com/repos/CicholGricenchos/rails/commits{/sha}","git_commits_url":"https://api.github.com/repos/CicholGricenchos/rails/git/commits{/sha}","comments_url":"https://api.github.com/repos/CicholGricenchos/rails/comments{/number}","issue_comment_url":"https://api.github.com/repos/CicholGricenchos/rails/issues/comments{/number}","contents_url":"https://api.github.com/repos/CicholGricenchos/rails/contents/{+path}","compare_url":"https://api.github.com/repos/CicholGricenchos/rails/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CicholGricenchos/rails/merges","archive_url":"https://api.github.com/repos/CicholGricenchos/rails/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CicholGricenchos/rails/downloads","issues_url":"https://api.github.com/repos/CicholGricenchos/rails/issues{/number}","pulls_url":"https://api.github.com/repos/CicholGricenchos/rails/pulls{/number}","milestones_url":"https://api.github.com/repos/CicholGricenchos/rails/milestones{/number}","notifications_url":"https://api.github.com/repos/CicholGricenchos/rails/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CicholGricenchos/rails/labels{/name}","releases_url":"https://api.github.com/repos/CicholGricenchos/rails/releases{/id}","deployments_url":"https://api.github.com/repos/CicholGricenchos/rails/deployments","created_at":"2017-08-04T14:05:59Z","updated_at":"2017-08-04T14:06:46Z","pushed_at":"2017-10-09T03:43:29Z","git_url":"git://github.com/CicholGricenchos/rails.git","ssh_url":"git@github.com:CicholGricenchos/rails.git","clone_url":"https://github.com/CicholGricenchos/rails.git","svn_url":"https://github.com/CicholGricenchos/rails","homepage":"http://rubyonrails.org","size":156088,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"rails:master","ref":"master","sha":"b1e7bb9ed7ddbb29fd788dee1c3f2ba2626bd7ac","user":{"login":"rails","id":4223,"avatar_url":"https://avatars1.githubusercontent.com/u/4223?v=4","gravatar_id":"","url":"https://api.github.com/users/rails","html_url":"https://github.com/rails","followers_url":"https://api.github.com/users/rails/followers","following_url":"https://api.github.com/users/rails/following{/other_user}","gists_url":"https://api.github.com/users/rails/gists{/gist_id}","starred_url":"https://api.github.com/users/rails/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rails/subscriptions","organizations_url":"https://api.github.com/users/rails/orgs","repos_url":"https://api.github.com/users/rails/repos","events_url":"https://api.github.com/users/rails/events{/privacy}","received_events_url":"https://api.github.com/users/rails/received_events","type":"Organization","site_admin":false},"repo":{"id":8514,"name":"rails","full_name":"rails/rails","owner":{"login":"rails","id":4223,"avatar_url":"https://avatars1.githubusercontent.com/u/4223?v=4","gravatar_id":"","url":"https://api.github.com/users/rails","html_url":"https://github.com/rails","followers_url":"https://api.github.com/users/rails/followers","following_url":"https://api.github.com/users/rails/following{/other_user}","gists_url":"https://api.github.com/users/rails/gists{/gist_id}","starred_url":"https://api.github.com/users/rails/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rails/subscriptions","organizations_url":"https://api.github.com/users/rails/orgs","repos_url":"https://api.github.com/users/rails/repos","events_url":"https://api.github.com/users/rails/events{/privacy}","received_events_url":"https://api.github.com/users/rails/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/rails/rails","description":"Ruby on Rails","fork":false,"url":"https://api.github.com/repos/rails/rails","forks_url":"https://api.github.com/repos/rails/rails/forks","keys_url":"https://api.github.com/repos/rails/rails/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rails/rails/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rails/rails/teams","hooks_url":"https://api.github.com/repos/rails/rails/hooks","issue_events_url":"https://api.github.com/repos/rails/rails/issues/events{/number}","events_url":"https://api.github.com/repos/rails/rails/events","assignees_url":"https://api.github.com/repos/rails/rails/assignees{/user}","branches_url":"https://api.github.com/repos/rails/rails/branches{/branch}","tags_url":"https://api.github.com/repos/rails/rails/tags","blobs_url":"https://api.github.com/repos/rails/rails/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rails/rails/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rails/rails/git/refs{/sha}","trees_url":"https://api.github.com/repos/rails/rails/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rails/rails/statuses/{sha}","languages_url":"https://api.github.com/repos/rails/rails/languages","stargazers_url":"https://api.github.com/repos/rails/rails/stargazers","contributors_url":"https://api.github.com/repos/rails/rails/contributors","subscribers_url":"https://api.github.com/repos/rails/rails/subscribers","subscription_url":"https://api.github.com/repos/rails/rails/subscription","commits_url":"https://api.github.com/repos/rails/rails/commits{/sha}","git_commits_url":"https://api.github.com/repos/rails/rails/git/commits{/sha}","comments_url":"https://api.github.com/repos/rails/rails/comments{/number}","issue_comment_url":"https://api.github.com/repos/rails/rails/issues/comments{/number}","contents_url":"https://api.github.com/repos/rails/rails/contents/{+path}","compare_url":"https://api.github.com/repos/rails/rails/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rails/rails/merges","archive_url":"https://api.github.com/repos/rails/rails/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rails/rails/downloads","issues_url":"https://api.github.com/repos/rails/rails/issues{/number}","pulls_url":"https://api.github.com/repos/rails/rails/pulls{/number}","milestones_url":"https://api.github.com/repos/rails/rails/milestones{/number}","notifications_url":"https://api.github.com/repos/rails/rails/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rails/rails/labels{/name}","releases_url":"https://api.github.com/repos/rails/rails/releases{/id}","deployments_url":"https://api.github.com/repos/rails/rails/deployments","created_at":"2008-04-11T02:19:47Z","updated_at":"2017-11-05T21:32:41Z","pushed_at":"2017-11-05T22:13:42Z","git_url":"git://github.com/rails/rails.git","ssh_url":"git@github.com:rails/rails.git","clone_url":"https://github.com/rails/rails.git","svn_url":"https://github.com/rails/rails","homepage":"http://rubyonrails.org","size":156809,"stargazers_count":37531,"watchers_count":37531,"language":"Ruby","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":15333,"mirror_url":null,"archived":false,"open_issues_count":1171,"forks":15333,"open_issues":1171,"watchers":37531,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/rails/rails/pulls/30076"},"html":{"href":"https://github.com/rails/rails/pull/30076"},"issue":{"href":"https://api.github.com/repos/rails/rails/issues/30076"},"comments":{"href":"https://api.github.com/repos/rails/rails/issues/30076/comments"},"review_comments":{"href":"https://api.github.com/repos/rails/rails/pulls/30076/comments"},"review_comment":{"href":"https://api.github.com/repos/rails/rails/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/rails/rails/pulls/30076/commits"},"statuses":{"href":"https://api.github.com/repos/rails/rails/statuses/5528cf169e55033b3da32ca1c826ad8c0e47510a"}},"author_association":"NONE","merged":false,"mergeable":null,"rebaseable":null,"mergeable_state":"unknown","merged_by":null,"comments":5,"review_comments":4,"maintainer_can_modify":false,"commits":1,"additions":81,"deletions":55,"changed_files":4}}
{"actor":{"display_login":"kamipo"}}