I''m a total Rails newbie and i''ve been struggling for hours today with one (prolly very silly) problem: I have a table portfolios that has many images: class Portfolio < ActiveRecord::Base has_many :images end class Image < ActiveRecord::Base belongs_to :portfolios end In the controller i define a list of active portfolios: @active_portfolios = Portfolio.find_all_by_is_active("1") In the view i render the list of portfolios: <%= render :partial => "portfolio_list", :collection => @active_portfolios %> in the partial collection _portfolio_list i need to get the image_url of the first image of the portfolio: <td class="col1"><img src="<%= portfolio_list.images[0].image_url -% >" /></td> This works fine if every portfolio has at least one image assigned to it. However, if a portfolio doesn''t have any images yet, the whole thing falls apart and the app exits with the error: "You have a nil object when you didn''t expect it!" I tried to get around it by doing this in the portfolio model: def get_first_image self.images[0].image_url || "default.jpg" end and then in the partial: <td class="col1"><img src="<%= portfolio_list.get_first_image -%>" / ></td> but the exact same thing happens. If every portfolio has at least one image it works well, if not, the error comes up. How can i avoid errors on nil objects and instead define alternatives (e.g. default.jpg) if a child attribute does not exist ? Thanks for your help. Sebastian -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060303/6625b811/attachment-0001.html
> > @active_portfolios = Portfolio.find_all_by_is_active("1") > > In the view i render the list of portfolios: > <%= render :partial => "portfolio_list", :collection => @active_portfolios > %> ><% unless portfolio.images[0].nil? -%> <td class="col1"><img src="<%= portfolio_list.images[0].image_url -%>" /></td> <% end -%>
That''s the ticket. :) Thank you so much. sebastian On Mar 3, 2006, at 12:43 AM, Nithin Reddy wrote:>> >> @active_portfolios = Portfolio.find_all_by_is_active("1") >> >> In the view i render the list of portfolios: >> <%= render :partial => "portfolio_list", :collection => >> @active_portfolios >> %> >> > <% unless portfolio.images[0].nil? -%> > <td class="col1"><img src="<%= portfolio_list.images[0].image_url > -%>" /></td> > <% end -%> > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
you were very close with your get_first_image method class Portfolio << ActiveRecord::Base ... # define a default image url DEFAULT_IMG = "default.jpg" # return the first image url in the portfolio or a default image if no images exist def first_image (images.empty?) ? DEFAULT_IMG : images[0].image_url end end then in your view: <img src="<%= portfolio.first_image -%>"/> this has the benefit of removing the logic from the view and into the portfolio where it belongs. On 3/3/06, Sebastian Friedrich <sebastian@feldpost.com> wrote:> > That''s the ticket. :) Thank you so much. > sebastian > On Mar 3, 2006, at 12:43 AM, Nithin Reddy wrote: > > >> > >> @active_portfolios = Portfolio.find_all_by_is_active("1") > >> > >> In the view i render the list of portfolios: > >> <%= render :partial => "portfolio_list", :collection => > >> @active_portfolios > >> %> > >> > > <% unless portfolio.images[0].nil? -%> > > <td class="col1"><img src="<%= portfolio_list.images[0].image_url > > -%>" /></td> > > <% end -%> > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060303/8bbf3065/attachment.html
I had ended up doing this in similar (but much uglier) way all in the view: <img src="<%= portfolio_list.images[0].nil? ? "default.jpg" : portfolio_list.images[0]. image_url -%>" /> but i certainly like your suggestion much better, especially when it comes to quickly changing the defaults etc. I''m still trying to get into the mindset of MVC separation and these kind of suggestions help very much. Thanks. Sebastian On Mar 3, 2006, at 9:07 AM, Chris Hall wrote:> you were very close with your get_first_image method > > class Portfolio << ActiveRecord::Base > ... > # define a default image url > DEFAULT_IMG = "default.jpg" > > # return the first image url in the portfolio or a default image > if no images exist > def first_image > (images.empty?) ? DEFAULT_IMG : images[0].image_url > end > end > > then in your view: > > <img src="<%= portfolio.first_image -%>"/> > > this has the benefit of removing the logic from the view and into > the portfolio where it belongs. > > On 3/3/06, Sebastian Friedrich <sebastian@feldpost.com> wrote: > That''s the ticket. :) Thank you so much. > sebastian > On Mar 3, 2006, at 12:43 AM, Nithin Reddy wrote: > > >> > >> @active_portfolios = Portfolio.find_all_by_is_active("1") > >> > >> In the view i render the list of portfolios: > >> <%= render :partial => "portfolio_list", :collection => > >> @active_portfolios > >> %> > >> > > <% unless portfolio.images[0].nil? -%> > > <td class="col1"><img src="<%= portfolio_list.images[0].image_url > > -%>" /></td> > > <% end -%> > > _______________________________________________ > > Rails mailing list > > Rails@lists.rubyonrails.org > > http://lists.rubyonrails.org/mailman/listinfo/rails > > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060303/cad0520c/attachment-0001.html
> class Portfolio << ActiveRecord::Base > ... > # define a default image url > DEFAULT_IMG = "default.jpg" > > # return the first image url in the portfolio or a default image if no > images exist > def first_image > (images.empty?) ? DEFAULT_IMG : images[0].image_url > end > end > > then in your view: > > <img src="<%= portfolio.first_image -%>"/> > > this has the benefit of removing the logic from the view and into the > portfolio where it belongs.good suggestion! for those of us without a C/C++ background: def first_image if images.empty? then DEFAULT_IMG else image[0].image_url end end