Search code examples
ruby-on-rails-4link-tolistings

Trying to view a product collection a user created and link_to/display in a separate view file


My users create collections and add listings to each collection. I have a main profile page for each user showing all collections created by that user. Now I want to link from each collection to an individual collection page showing all listings in that collection.

My user view file to show all collections:

<% @collections.each do |collection| %>
    <%= image_tag listing.image.url(:thumb) %>
    <%= link_to "#{collection.name}", shopcollected_path(collection_id: @collection) %>
<% end %>

When I click on my link I'm taken to the individual collection page (shopcollected.html.erb) just fine, but the listings for that collection aren't being recognized and the page is empty of listings. I know I'm missing one small part, but am stuck again on what that is. I'm still learning about retrieving objects from databases and linking.

My listings_controller:

def shopcollections
    @user = User.find(params[:id])
    @collections = Collection.where(user: User.find(params[:id])).order("created_at DESC")
end

def shopcollected
    @user = User.find(params[:id])
    @listings = Listing.where(collection: :collection_id)
end

My individual user 'shopcollected' view file:

<% @listings.each do |listing| %>
    <%= image_tag listing.image.url(:medium) %>
    <%= listing.name %>`
<% end %>

What am I missing? I believe I need to call all listings by collection, but in order to do so, where do I need to make a change in my code?


Solution

  • So as we discussed in the comments, there were two issues afflicting your application:

    In the user view, when you were iterating over the collection of @collections, you were using the wrong variable inside the loop to refer to the current Collection object (specifically, @collection instead of collection). Should look like this:

    <% @collections.each do |collection| %>
        <%= image_tag listing.image.url(:thumb) %>
        <%= link_to "#{collection.name}", shopcollected_path(collection_id: collection) %>
    <% end %>
    

    The other issue was in the shopcollected controller method. You simply forgot to include the params portion when attempting to access the :collection_id value from the form. It should look like this:

    def shopcollected
        @user = User.find(params[:id])
        @listings = Listing.where(collection: params[:collection_id])
    end
    

    One minor unrelated suggestion, which will have no impact on performance but will slightly clean up your code and make it more Rails-y looking; in the case of the shopcollections, assuming you've set up the proper belongs_to and has_many associations in the models, there's a slightly shorter way of looking up the collections for the specific user, like so:

    def shopcollections
        @user = User.find(params[:id])
        @collections = @user.collections.order("created_at DESC")
    end
    

    This will have the same affect as your previous version because Rails will load all the collections for that user, because you're invoking the has_many relationship method. Since most active record methods return a proxy, you can further invoke other methods like order which will now affect the filtration and ordering of the invoked has_many collection (in this case, the Collection objects). Hope that makes sense,