Displaying has_many through









up vote
0
down vote

favorite












I have a quick question about displaying a has many through associations.



I have the below associations set up in 3 different models



assignment.rb 
class Assignment < ApplicationRecord
belongs_to :stock
belongs_to :portfolio
end

portfolio.rb
class Portfolio < ApplicationRecord
has_many :assignments
has_many :stocks, through: :assignments
accepts_nested_attributes_for :stocks
end

stock.rb
class Stock < ApplicationRecord
has_many :assignments
has_many :portfolios, through: :assignments
end


and what i am trying to do is display all the stocks that a portfolio has on the portfolio index page after you assign a stock to a portfolio



I currently have this in my portfolio index view



<% @portfolios.stocks.each do |a|%>
<p><%= a.ticker %></p>
<%end%>


but i am getting the below error



undefined method `stocks' for #<Portfolio::ActiveRecord_Relation:0x51f0fd8>


i don't understand what i am doing wrong










share|improve this question





















  • You're trying to get stocks on portfolios in the example you mentioned. You can get stocks of a portfolio by writing @portfolios.first.stocks. .stocks works on a ActiveModel::Model not ActiveModel::Model
    – Anmol
    Nov 10 at 22:03











  • can you show your controller method as well?
    – Gagan Gupta
    Nov 10 at 22:14










  • If you still need all the stocks for @portfolios then you can write Stock.joins(:portfolios).where(portfolios: id: @portfolios.pluck(:id) )
    – Anmol
    Nov 10 at 22:19














up vote
0
down vote

favorite












I have a quick question about displaying a has many through associations.



I have the below associations set up in 3 different models



assignment.rb 
class Assignment < ApplicationRecord
belongs_to :stock
belongs_to :portfolio
end

portfolio.rb
class Portfolio < ApplicationRecord
has_many :assignments
has_many :stocks, through: :assignments
accepts_nested_attributes_for :stocks
end

stock.rb
class Stock < ApplicationRecord
has_many :assignments
has_many :portfolios, through: :assignments
end


and what i am trying to do is display all the stocks that a portfolio has on the portfolio index page after you assign a stock to a portfolio



I currently have this in my portfolio index view



<% @portfolios.stocks.each do |a|%>
<p><%= a.ticker %></p>
<%end%>


but i am getting the below error



undefined method `stocks' for #<Portfolio::ActiveRecord_Relation:0x51f0fd8>


i don't understand what i am doing wrong










share|improve this question





















  • You're trying to get stocks on portfolios in the example you mentioned. You can get stocks of a portfolio by writing @portfolios.first.stocks. .stocks works on a ActiveModel::Model not ActiveModel::Model
    – Anmol
    Nov 10 at 22:03











  • can you show your controller method as well?
    – Gagan Gupta
    Nov 10 at 22:14










  • If you still need all the stocks for @portfolios then you can write Stock.joins(:portfolios).where(portfolios: id: @portfolios.pluck(:id) )
    – Anmol
    Nov 10 at 22:19












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have a quick question about displaying a has many through associations.



I have the below associations set up in 3 different models



assignment.rb 
class Assignment < ApplicationRecord
belongs_to :stock
belongs_to :portfolio
end

portfolio.rb
class Portfolio < ApplicationRecord
has_many :assignments
has_many :stocks, through: :assignments
accepts_nested_attributes_for :stocks
end

stock.rb
class Stock < ApplicationRecord
has_many :assignments
has_many :portfolios, through: :assignments
end


and what i am trying to do is display all the stocks that a portfolio has on the portfolio index page after you assign a stock to a portfolio



I currently have this in my portfolio index view



<% @portfolios.stocks.each do |a|%>
<p><%= a.ticker %></p>
<%end%>


but i am getting the below error



undefined method `stocks' for #<Portfolio::ActiveRecord_Relation:0x51f0fd8>


i don't understand what i am doing wrong










share|improve this question













I have a quick question about displaying a has many through associations.



I have the below associations set up in 3 different models



assignment.rb 
class Assignment < ApplicationRecord
belongs_to :stock
belongs_to :portfolio
end

portfolio.rb
class Portfolio < ApplicationRecord
has_many :assignments
has_many :stocks, through: :assignments
accepts_nested_attributes_for :stocks
end

stock.rb
class Stock < ApplicationRecord
has_many :assignments
has_many :portfolios, through: :assignments
end


and what i am trying to do is display all the stocks that a portfolio has on the portfolio index page after you assign a stock to a portfolio



I currently have this in my portfolio index view



<% @portfolios.stocks.each do |a|%>
<p><%= a.ticker %></p>
<%end%>


but i am getting the below error



undefined method `stocks' for #<Portfolio::ActiveRecord_Relation:0x51f0fd8>


i don't understand what i am doing wrong







ruby-on-rails ruby






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 10 at 21:58









Joseph Parker

81




81











  • You're trying to get stocks on portfolios in the example you mentioned. You can get stocks of a portfolio by writing @portfolios.first.stocks. .stocks works on a ActiveModel::Model not ActiveModel::Model
    – Anmol
    Nov 10 at 22:03











  • can you show your controller method as well?
    – Gagan Gupta
    Nov 10 at 22:14










  • If you still need all the stocks for @portfolios then you can write Stock.joins(:portfolios).where(portfolios: id: @portfolios.pluck(:id) )
    – Anmol
    Nov 10 at 22:19
















  • You're trying to get stocks on portfolios in the example you mentioned. You can get stocks of a portfolio by writing @portfolios.first.stocks. .stocks works on a ActiveModel::Model not ActiveModel::Model
    – Anmol
    Nov 10 at 22:03











  • can you show your controller method as well?
    – Gagan Gupta
    Nov 10 at 22:14










  • If you still need all the stocks for @portfolios then you can write Stock.joins(:portfolios).where(portfolios: id: @portfolios.pluck(:id) )
    – Anmol
    Nov 10 at 22:19















You're trying to get stocks on portfolios in the example you mentioned. You can get stocks of a portfolio by writing @portfolios.first.stocks. .stocks works on a ActiveModel::Model not ActiveModel::Model
– Anmol
Nov 10 at 22:03





You're trying to get stocks on portfolios in the example you mentioned. You can get stocks of a portfolio by writing @portfolios.first.stocks. .stocks works on a ActiveModel::Model not ActiveModel::Model
– Anmol
Nov 10 at 22:03













can you show your controller method as well?
– Gagan Gupta
Nov 10 at 22:14




can you show your controller method as well?
– Gagan Gupta
Nov 10 at 22:14












If you still need all the stocks for @portfolios then you can write Stock.joins(:portfolios).where(portfolios: id: @portfolios.pluck(:id) )
– Anmol
Nov 10 at 22:19




If you still need all the stocks for @portfolios then you can write Stock.joins(:portfolios).where(portfolios: id: @portfolios.pluck(:id) )
– Anmol
Nov 10 at 22:19












2 Answers
2






active

oldest

votes

















up vote
0
down vote



accepted










An ActiveRecord::Relation is an array like object containing several records. In your case Portfolio instances.



To call instance methods on the records (like #stocks) you need to iterate through the collection:



<% @portfolios.each do |portfolio|%>
<div class="portfolio">
<% portfolio.stocks.each do |stock| %>
<p><%= stock.ticker %></p>
<% end %>
</div>
<% end %>


When doing this make sure to use .includes or .eager_load to avoid a N+1 query:



def index
@portfolios = Portfolio.includes(:stocks).all
end





share|improve this answer





























    up vote
    0
    down vote













    Here you've defined that you've a many to many relationship between portfolios and stocks.



    which means for every porfolio you've multiple records of stocks.



    So, to get all the stocks related to a portfolio you'll have to use some_porfolio.stocks



    your code is not working because you're using an array of active_record and you are asking it to fetch stocks for all the portfolios in one go but relationship is not between array of active_records and array of active_records. Instead it's between a single active_record holding foreign_key of another active record.



    If you want to show a list of stocks against the record of a portfolio then it's better to use



    <% @portfolios.each do |porfolio| %>
    <!--- your html code for each portfolio -->
    ID: <%= portfolio.id %>
    <!--- your html code for each stock associated to this portfolio -->
    <% portfolio.stocks.each do |stock| %>
    <!--- your html code for each stock -->
    ID: <%= stock.id %>
    <% end %>
    <% end %>





    share|improve this answer




















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













       

      draft saved


      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243820%2fdisplaying-has-many-through%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      0
      down vote



      accepted










      An ActiveRecord::Relation is an array like object containing several records. In your case Portfolio instances.



      To call instance methods on the records (like #stocks) you need to iterate through the collection:



      <% @portfolios.each do |portfolio|%>
      <div class="portfolio">
      <% portfolio.stocks.each do |stock| %>
      <p><%= stock.ticker %></p>
      <% end %>
      </div>
      <% end %>


      When doing this make sure to use .includes or .eager_load to avoid a N+1 query:



      def index
      @portfolios = Portfolio.includes(:stocks).all
      end





      share|improve this answer


























        up vote
        0
        down vote



        accepted










        An ActiveRecord::Relation is an array like object containing several records. In your case Portfolio instances.



        To call instance methods on the records (like #stocks) you need to iterate through the collection:



        <% @portfolios.each do |portfolio|%>
        <div class="portfolio">
        <% portfolio.stocks.each do |stock| %>
        <p><%= stock.ticker %></p>
        <% end %>
        </div>
        <% end %>


        When doing this make sure to use .includes or .eager_load to avoid a N+1 query:



        def index
        @portfolios = Portfolio.includes(:stocks).all
        end





        share|improve this answer
























          up vote
          0
          down vote



          accepted







          up vote
          0
          down vote



          accepted






          An ActiveRecord::Relation is an array like object containing several records. In your case Portfolio instances.



          To call instance methods on the records (like #stocks) you need to iterate through the collection:



          <% @portfolios.each do |portfolio|%>
          <div class="portfolio">
          <% portfolio.stocks.each do |stock| %>
          <p><%= stock.ticker %></p>
          <% end %>
          </div>
          <% end %>


          When doing this make sure to use .includes or .eager_load to avoid a N+1 query:



          def index
          @portfolios = Portfolio.includes(:stocks).all
          end





          share|improve this answer














          An ActiveRecord::Relation is an array like object containing several records. In your case Portfolio instances.



          To call instance methods on the records (like #stocks) you need to iterate through the collection:



          <% @portfolios.each do |portfolio|%>
          <div class="portfolio">
          <% portfolio.stocks.each do |stock| %>
          <p><%= stock.ticker %></p>
          <% end %>
          </div>
          <% end %>


          When doing this make sure to use .includes or .eager_load to avoid a N+1 query:



          def index
          @portfolios = Portfolio.includes(:stocks).all
          end






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 11 at 11:07

























          answered Nov 11 at 11:01









          max

          43.9k856103




          43.9k856103






















              up vote
              0
              down vote













              Here you've defined that you've a many to many relationship between portfolios and stocks.



              which means for every porfolio you've multiple records of stocks.



              So, to get all the stocks related to a portfolio you'll have to use some_porfolio.stocks



              your code is not working because you're using an array of active_record and you are asking it to fetch stocks for all the portfolios in one go but relationship is not between array of active_records and array of active_records. Instead it's between a single active_record holding foreign_key of another active record.



              If you want to show a list of stocks against the record of a portfolio then it's better to use



              <% @portfolios.each do |porfolio| %>
              <!--- your html code for each portfolio -->
              ID: <%= portfolio.id %>
              <!--- your html code for each stock associated to this portfolio -->
              <% portfolio.stocks.each do |stock| %>
              <!--- your html code for each stock -->
              ID: <%= stock.id %>
              <% end %>
              <% end %>





              share|improve this answer
























                up vote
                0
                down vote













                Here you've defined that you've a many to many relationship between portfolios and stocks.



                which means for every porfolio you've multiple records of stocks.



                So, to get all the stocks related to a portfolio you'll have to use some_porfolio.stocks



                your code is not working because you're using an array of active_record and you are asking it to fetch stocks for all the portfolios in one go but relationship is not between array of active_records and array of active_records. Instead it's between a single active_record holding foreign_key of another active record.



                If you want to show a list of stocks against the record of a portfolio then it's better to use



                <% @portfolios.each do |porfolio| %>
                <!--- your html code for each portfolio -->
                ID: <%= portfolio.id %>
                <!--- your html code for each stock associated to this portfolio -->
                <% portfolio.stocks.each do |stock| %>
                <!--- your html code for each stock -->
                ID: <%= stock.id %>
                <% end %>
                <% end %>





                share|improve this answer






















                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  Here you've defined that you've a many to many relationship between portfolios and stocks.



                  which means for every porfolio you've multiple records of stocks.



                  So, to get all the stocks related to a portfolio you'll have to use some_porfolio.stocks



                  your code is not working because you're using an array of active_record and you are asking it to fetch stocks for all the portfolios in one go but relationship is not between array of active_records and array of active_records. Instead it's between a single active_record holding foreign_key of another active record.



                  If you want to show a list of stocks against the record of a portfolio then it's better to use



                  <% @portfolios.each do |porfolio| %>
                  <!--- your html code for each portfolio -->
                  ID: <%= portfolio.id %>
                  <!--- your html code for each stock associated to this portfolio -->
                  <% portfolio.stocks.each do |stock| %>
                  <!--- your html code for each stock -->
                  ID: <%= stock.id %>
                  <% end %>
                  <% end %>





                  share|improve this answer












                  Here you've defined that you've a many to many relationship between portfolios and stocks.



                  which means for every porfolio you've multiple records of stocks.



                  So, to get all the stocks related to a portfolio you'll have to use some_porfolio.stocks



                  your code is not working because you're using an array of active_record and you are asking it to fetch stocks for all the portfolios in one go but relationship is not between array of active_records and array of active_records. Instead it's between a single active_record holding foreign_key of another active record.



                  If you want to show a list of stocks against the record of a portfolio then it's better to use



                  <% @portfolios.each do |porfolio| %>
                  <!--- your html code for each portfolio -->
                  ID: <%= portfolio.id %>
                  <!--- your html code for each stock associated to this portfolio -->
                  <% portfolio.stocks.each do |stock| %>
                  <!--- your html code for each stock -->
                  ID: <%= stock.id %>
                  <% end %>
                  <% end %>






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 10 at 22:26









                  Gagan Gupta

                  750317




                  750317



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243820%2fdisplaying-has-many-through%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      這個網誌中的熱門文章

                      How to read a connectionString WITH PROVIDER in .NET Core?

                      Node.js Script on GitHub Pages or Amazon S3

                      Museum of Modern and Contemporary Art of Trento and Rovereto