Note that there are some explanatory texts on larger screens.

plurals
  1. PORails has_many :through using same table twice
    primarykey
    data
    text
    <p>I am having issues getting my Model relationships set up correctly. I have the following classes:</p> <p><strong>personal_portfolio.rb</strong></p> <pre><code>class PersonalPortfolio &lt; Portfolio has_many :user_stake_in_portfolios, :foreign_key =&gt; :possession_id belongs_to :owner, :class_name =&gt; 'User' has_many :managers, :through =&gt; :user_stake_in_portfolios, :source =&gt; :user has_many :company_permissions, :foreign_key =&gt; :owner_id has_many :company_permissions_as_viewer, :class_name =&gt; 'CompanyPermission', :foreign_key =&gt; :owner_id, :conditions =&gt; 'can_view_info = true || can_edit_cap_table = true || can_view_key_metric = true || can_view_all_metrics = true || can_view_cap_table = true || can_edit_managers = true || can_edit_info = true || can_edit_metrics = true' has_many :companies_as_viewer, :class_name =&gt; 'Company', :through =&gt; :company_permissions_as_viewer, :source =&gt; :entity has_many :company_permissions_as_manager, :class_name =&gt; 'CompanyPermission', :foreign_key =&gt; :owner_id, :conditions =&gt; { :can_edit_managers =&gt; true } has_many :companies_as_manager, :class_name =&gt; 'Company', :through =&gt; :company_permissions_as_manager, :source =&gt; :entity has_many :portfolio_permissions, :foreign_key =&gt; :owner_id has_many :portfolio_permissions_as_viewer, :class_name =&gt; 'PortfolioPermission', :foreign_key =&gt; :owner_id, :conditions =&gt; 'can_view_info = true || can_edit_cap_table = true || can_view_key_metric = true || can_view_all_metrics = true || can_view_cap_table = true || can_edit_managers = true || can_edit_info = true || can_edit_metrics = true' has_many :portfolios_as_viewer, :class_name =&gt; 'Portfolio', :through =&gt; :portfolio_permissions_as_viewer, :source =&gt; :entity has_many :portfolio_permissions_as_manager, :class_name =&gt; 'PortfolioPermission', :foreign_key =&gt; :owner_id, :conditions =&gt; { :can_edit_managers =&gt; true } has_many :portfolios_as_manager, :class_name =&gt; 'GroupPortfolio', :through =&gt; :portfolio_permissions_as_manager, :source =&gt; :entity after_create :add_manager ... end </code></pre> <p><strong>user.rb</strong></p> <pre><code>class User &lt; ActiveRecord::Base ... has_many :user_stake_in_portfolios, foreign_key: :owner_id has_many :portfolios, through: :user_stake_in_portfolios has_many :personal_portfolios, through: :user_stake_in_portfolios, :class_name =&gt; 'PersonalPortfolio', :source =&gt; :portfolio, :conditions =&gt; { :type =&gt; 'PersonalPortfolio' } has_many :companies, through: :portfolios, source: :portfolio_companies, class_name: 'Company' has_many :managed_portfolios, :through =&gt; :personal_portfolios, :source =&gt; :portfolios_as_manager has_many :viewable_portfolios, :through =&gt; :personal_portfolios, :source =&gt; :portfolios_as_viewer has_many :managed_companies, :through =&gt; :personal_portfolios, :source =&gt; :companies_as_manager has_many :viewable_companies, :through =&gt; :personal_portfolios, :source =&gt; :companies_as_viewer ... end </code></pre> <p>What is strange is that if I run the command <code>User.find(3).personal_portfolios.first.portfolios_as_viewer</code> I get the results I expect (3 portfolios). But the issue is when I then try <code>User.find(3).viewable_portfolios</code>, I only get 1 portfolio (which is 1 of the three). User.<code>viewable_portfolios</code> is a <code>has_many :through</code> using <code>PersonalPortfolio.portfolios_as_viewer</code> as the source.</p> <p>When looking at the query produced by the second command, you can see that it is using the <code>portfolios</code> table twice:</p> <pre><code>SELECT `portfolios`.* FROM `portfolios` INNER JOIN `permissions` ON `portfolios`.`id` = `permissions`.`entity_id` INNER JOIN `portfolios` `personal_portfolios_viewable_portfolios_join` ON `permissions`.`owner_id` = `personal_portfolios_viewable_portfolios_join`.`id` INNER JOIN `stakes` ON `personal_portfolios_viewable_portfolios_join`.`id` = `stakes`.`possession_id` WHERE `permissions`.`type` IN ( 'PortfolioPermission' ) AND `portfolios`.`type` IN ( 'PersonalPortfolio' ) AND `stakes`.`type` IN ( 'UserStakeInPortfolio' ) AND `stakes`.`owner_id` = 3 AND ( can_view_info = true || can_edit_cap_table = true || can_view_key_metric = true || can_view_all_metrics = true || can_view_cap_table = true || can_edit_managers = true || can_edit_info = true || can_edit_metrics = true ) AND ( `personal_portfolios_viewable_portfolios_join`.`type` = 'PersonalPortfolio' ) </code></pre> <p>It's strange to me because <code>User.find(3).managed_portfolios == User.find(3).personal_portfolios.first.portfolios_as_manager</code> returns true while <code>User.find(3).viewable_portfolios == User.find(3).personal_portfolios.first.portfolios_as_viewer</code> returns false. And companies work just fine (though not indicative of the right relationships as the dependencies/data vary) though the relationships look to be the same.</p> <p><strong>The Question</strong> How can I get <code>User.find(3).viewable_portfolios</code> return the same as <code>User.find(3).personal_portfolios.first.portfolios_as_viewer</code>?</p> <p><strong>Helpful Outputs</strong></p> <pre><code>1.9.3-p362 :122 &gt; User.find(3).viewable_portfolios User Load (0.8ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1 Portfolio Load (1.1ms) SELECT `portfolios`.* FROM `portfolios` INNER JOIN `permissions` ON `portfolios`.`id` = `permissions`.`entity_id` INNER JOIN `portfolios` `personal_portfolios_viewable_portfolios_join` ON `permissions`.`owner_id` = `personal_portfolios_viewable_portfolios_join`.`id` INNER JOIN `stakes` ON `personal_portfolios_viewable_portfolios_join`.`id` = `stakes`.`possession_id` WHERE `permissions`.`type` IN ('PortfolioPermission') AND `portfolios`.`type` IN ('PersonalPortfolio') AND `stakes`.`type` IN ('UserStakeInPortfolio') AND `stakes`.`owner_id` = 3 AND (can_view_info = true || can_edit_cap_table = true || can_view_key_metric = true || can_view_all_metrics = true || can_view_cap_table = true || can_edit_managers = true || can_edit_info = true || can_edit_metrics = true) AND (`personal_portfolios_viewable_portfolios_join`.`type` = 'PersonalPortfolio') =&gt; [#&lt;PersonalPortfolio id: 3, name: "Manager Man's portfolio", established: "2013-09-24", created_at: "2013-09-24 23:20:34", updated_at: "2013-09-24 23:20:34", type: "PersonalPortfolio", base_capital_invested: nil, total_shares: nil, logo_file_name: nil, logo_content_type: nil, logo_file_size: nil, logo_updated_at: nil, city: nil, state: nil, invited_manager_email: nil, claim_code: nil, angellist_url: nil, facebook_url: nil, linkedin_url: nil, twitter_url: nil, website_url: nil, longitude: nil, latitude: nil, is_single_use_fund: false, tagline: nil, thumb_file_name: nil, thumb_content_type: nil, thumb_file_size: nil, thumb_updated_at: nil, use_committed_capital: true, owner_id: 3&gt;] 1.9.3-p362 :123 &gt; User.find(3).viewable_portfolios.count User Load (0.9ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1 (2.2ms) SELECT COUNT(*) FROM `portfolios` INNER JOIN `permissions` ON `portfolios`.`id` = `permissions`.`entity_id` INNER JOIN `portfolios` `personal_portfolios_viewable_portfolios_join` ON `permissions`.`owner_id` = `personal_portfolios_viewable_portfolios_join`.`id` INNER JOIN `stakes` ON `personal_portfolios_viewable_portfolios_join`.`id` = `stakes`.`possession_id` WHERE `permissions`.`type` IN ('PortfolioPermission') AND `portfolios`.`type` IN ('PersonalPortfolio') AND `stakes`.`type` IN ('UserStakeInPortfolio') AND `stakes`.`owner_id` = 3 AND (can_view_info = true || can_edit_cap_table = true || can_view_key_metric = true || can_view_all_metrics = true || can_view_cap_table = true || can_edit_managers = true || can_edit_info = true || can_edit_metrics = true) AND (`personal_portfolios_viewable_portfolios_join`.`type` = 'PersonalPortfolio') =&gt; 1 1.9.3-p362 :124 &gt; User.find(3).personal_portfolios.first.portfolios_as_viewer User Load (0.9ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1 PersonalPortfolio Load (0.8ms) SELECT `portfolios`.* FROM `portfolios` INNER JOIN `stakes` ON `portfolios`.`id` = `stakes`.`possession_id` WHERE `stakes`.`type` IN ('UserStakeInPortfolio') AND `portfolios`.`type` IN ('PersonalPortfolio') AND `stakes`.`owner_id` = 3 AND (`portfolios`.`type` = 'PersonalPortfolio') LIMIT 1 Portfolio Load (1.0ms) SELECT `portfolios`.* FROM `portfolios` INNER JOIN `permissions` ON `portfolios`.`id` = `permissions`.`entity_id` WHERE `permissions`.`type` IN ('PortfolioPermission') AND `permissions`.`owner_id` = 3 AND (can_view_info = true || can_edit_cap_table = true || can_view_key_metric = true || can_view_all_metrics = true || can_view_cap_table = true || can_edit_managers = true || can_edit_info = true || can_edit_metrics = true) =&gt; [#&lt;PersonalPortfolio id: 3, name: "Manager Man's portfolio", established: "2013-09-24", created_at: "2013-09-24 23:20:34", updated_at: "2013-09-24 23:20:34", type: "PersonalPortfolio", base_capital_invested: nil, total_shares: nil, logo_file_name: nil, logo_content_type: nil, logo_file_size: nil, logo_updated_at: nil, city: nil, state: nil, invited_manager_email: nil, claim_code: nil, angellist_url: nil, facebook_url: nil, linkedin_url: nil, twitter_url: nil, website_url: nil, longitude: nil, latitude: nil, is_single_use_fund: false, tagline: nil, thumb_file_name: nil, thumb_content_type: nil, thumb_file_size: nil, thumb_updated_at: nil, use_committed_capital: true, owner_id: 3&gt;, #&lt;GroupPortfolio id: 5, name: "New Fund, LLC", established: "2009-01-01", created_at: "2013-09-24 23:20:36", updated_at: "2013-09-24 23:20:36", type: "GroupPortfolio", base_capital_invested: 2000000, total_shares: 1000000, logo_file_name: nil, logo_content_type: nil, logo_file_size: nil, logo_updated_at: nil, city: "Hamlin", state: "WV", invited_manager_email: nil, claim_code: nil, angellist_url: nil, facebook_url: nil, linkedin_url: nil, twitter_url: nil, website_url: nil, longitude: -82.1029, latitude: 38.2787, is_single_use_fund: false, tagline: nil, thumb_file_name: nil, thumb_content_type: nil, thumb_file_size: nil, thumb_updated_at: nil, use_committed_capital: false, owner_id: nil&gt;, #&lt;GroupPortfolio id: 6, name: "SB, LLC", established: "2009-01-01", created_at: "2013-09-24 23:20:36", updated_at: "2013-09-24 23:20:36", type: "GroupPortfolio", base_capital_invested: 2000000, total_shares: 2000000, logo_file_name: nil, logo_content_type: nil, logo_file_size: nil, logo_updated_at: nil, city: "Bloomington", state: "IN", invited_manager_email: nil, claim_code: nil, angellist_url: nil, facebook_url: nil, linkedin_url: nil, twitter_url: nil, website_url: nil, longitude: -86.5264, latitude: 39.1653, is_single_use_fund: false, tagline: nil, thumb_file_name: nil, thumb_content_type: nil, thumb_file_size: nil, thumb_updated_at: nil, use_committed_capital: true, owner_id: nil&gt;] 1.9.3-p362 :125 &gt; User.find(3).personal_portfolios.first.portfolios_as_viewer.count User Load (0.6ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1 PersonalPortfolio Load (0.5ms) SELECT `portfolios`.* FROM `portfolios` INNER JOIN `stakes` ON `portfolios`.`id` = `stakes`.`possession_id` WHERE `stakes`.`type` IN ('UserStakeInPortfolio') AND `portfolios`.`type` IN ('PersonalPortfolio') AND `stakes`.`owner_id` = 3 AND (`portfolios`.`type` = 'PersonalPortfolio') LIMIT 1 (0.7ms) SELECT COUNT(*) FROM `portfolios` INNER JOIN `permissions` ON `portfolios`.`id` = `permissions`.`entity_id` WHERE `permissions`.`type` IN ('PortfolioPermission') AND `permissions`.`owner_id` = 3 AND (can_view_info = true || can_edit_cap_table = true || can_view_key_metric = true || can_view_all_metrics = true || can_view_cap_table = true || can_edit_managers = true || can_edit_info = true || can_edit_metrics = true) =&gt; 3 1.9.3-p362 :126 &gt; User.find(3).personal_portfolios User Load (0.9ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1 PersonalPortfolio Load (0.5ms) SELECT `portfolios`.* FROM `portfolios` INNER JOIN `stakes` ON `portfolios`.`id` = `stakes`.`possession_id` WHERE `stakes`.`type` IN ('UserStakeInPortfolio') AND `portfolios`.`type` IN ('PersonalPortfolio') AND `stakes`.`owner_id` = 3 AND (`portfolios`.`type` = 'PersonalPortfolio') =&gt; [#&lt;PersonalPortfolio id: 3, name: "Manager Man's portfolio", established: "2013-09-24", created_at: "2013-09-24 23:20:34", updated_at: "2013-09-24 23:20:34", type: "PersonalPortfolio", base_capital_invested: nil, total_shares: nil, logo_file_name: nil, logo_content_type: nil, logo_file_size: nil, logo_updated_at: nil, city: nil, state: nil, invited_manager_email: nil, claim_code: nil, angellist_url: nil, facebook_url: nil, linkedin_url: nil, twitter_url: nil, website_url: nil, longitude: nil, latitude: nil, is_single_use_fund: false, tagline: nil, thumb_file_name: nil, thumb_content_type: nil, thumb_file_size: nil, thumb_updated_at: nil, use_committed_capital: true, owner_id: 3&gt;] 1.9.3-p362 :127 &gt; User.find(3).personal_portfolios.count User Load (0.8ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1 (0.4ms) SELECT COUNT(*) FROM `portfolios` INNER JOIN `stakes` ON `portfolios`.`id` = `stakes`.`possession_id` WHERE `stakes`.`type` IN ('UserStakeInPortfolio') AND `portfolios`.`type` IN ('PersonalPortfolio') AND `stakes`.`owner_id` = 3 AND (`portfolios`.`type` = 'PersonalPortfolio') =&gt; 1 </code></pre> <p><strong>Another Variation (for illustration/simplicity</strong></p> <p>If I change the definition in <code>personal_portfolio.rb</code> to:</p> <pre><code>has_many :portfolio_permissions_as_viewer, :class_name =&gt; 'PortfolioPermission', :foreign_key =&gt; :owner_id, :conditions =&gt; { :can_view_info =&gt; true } </code></pre> <p><code>User.find(3).viewable_portfolios == User.find(3).personal_portfolios.first.portfolios_as_viewer</code> still returns false. But <code>User.find(3).viewable_portfolios</code></p> <pre><code>SELECT `portfolios`.* FROM `portfolios` INNER JOIN `permissions` ON `portfolios`.`id` = `permissions`.`entity_id` INNER JOIN `portfolios` `personal_portfolios_viewable_portfolios_join` ON `permissions`.`owner_id` = `personal_portfolios_viewable_portfolios_join`.`id` INNER JOIN `stakes` ON `personal_portfolios_viewable_portfolios_join`.`id` = `stakes`.`possession_id` WHERE `permissions`.`type` IN ( 'PortfolioPermission' ) AND `portfolios`.`type` IN ( 'PersonalPortfolio' ) AND `stakes`.`type` IN ( 'UserStakeInPortfolio' ) AND `stakes`.`owner_id` = 3 AND ( `permissions`.`can_view_info` = 1 ) AND ( `personal_portfolios_viewable_portfolios_join`.`type` = 'PersonalPortfolio' ) </code></pre> <p>I think the issue is that it is requiring both <code>portfolios</code> and <code>personal_portfolios_viewable_portfolios_join</code> to be a <code>PersonalPortfolio</code> when in fact <code>portfolios</code> should be of any type. This leads me to believe it is how I have the relationships set up, but not 100% sure.</p> <p><strong>Need more?</strong> Let me know if you need more information/code. I tried not to be too superfluous but might have not given enough to be helpful.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload