Reputation: 41
Assuming that the "books/book" partial below is being called from multiple locations (like: author#show view, categogories#show view, categories#index view) and i only want the votes partial called from the author#show view. That is, i want the books collection returned from the books partial (@upvoted_books) to each render the "votes/vote" partail so that authors are able to vote on a book from their author#show view. Is the following code or a variation of it sensible?
<%= render partial: "books/book", collection: @upvoted_books do |upvoted| %>
<%= render partial: "votes/vote", locals: {category: book.category, book: upvoted } %>
<% end %>
p.s: I have tried this particular code here and it doesnt work in my project but i was just wondering if something similar to it could work but it doesnt throw any apparent error either. Maybe i was just getting the syntax a bit mixed up. I alos know a few other ways to solve the same problem but i was looking for something more elegant. Thanks in anticipationm of your creative responses.
update:
Thanks @Deep, for your very insightful solution. What I have done to solve the problem before is calling the line below from "books/book" partial:
<% if defined?(@upvoted_books) && @upvoted_books.include?(book) %>
<%= render partial: "votes/vote", locals: {category: book.category, book: upvoted } %>
<% end %>
That works but i'm not sure it has some significant code-smell or if its syntatically awkward. What do you think?
Final update:
@Deep these are the views you asked for: This is my category#show view :
`<h1>Topics#show</h1>
<p><%= @category.title %></p>
<%= render partial: "books/form", locals: {topic: @category, book: Book.new} %>
<%= link_to "edit category", edit_author_category_path(@category.author, @category) %>
<p> Books you have Authored </p>
<%= render partial: "books/book", collection: @category.books %>`
And this is my books/_book.html.erb partial now
`<% if defined?(upvoted_book) && current_author.books.include?(upvoted_book) %>
<h5>Created by <%= upvoted_book.category.author.name || upvoted_book.category.author.email %> on <%= upvoted_book.created_at %></h>
<br>
<%= link_to upvoted_book.title, category_book_path(upvoted_book.category, upvoted_book) %>
<% if policy(Vote.new).create? %>
<%= render partial: "votes/vote", locals: {category: upvoted_book.category, book: upvoted_book} %>
<br>
<% end %>
<% else %>
<h5>Created by <%= book.category.author.name || book.category.author.email %> on <%= book.created_at %></h>
<br>
<%= link_to book.title, category_book_path(book.category, book) %>
<%= link_to "Remove book", category_book_path(book.category, book), method: :delete, data: { confirm: "Are you sure you want to delete this book?" } %>
<% end %>`
As you can see, i refer to local variables book and upvoted_book in the partial. This is how i called the partial from the author#show view : `
<%= render partial: "categories/form", locals: {category: Category.new, author: @author} %>
<p> Categories and Books you have Writen: </p>
<%= render partial: "categories/category", collection: @categories %>
<p> Books from all authors that you have Upvoted: </p>
<%= render partial: "books/book", collection: @upvoted_books, as: :upvoted_book %>
<br> `
Thanks for you wonderful insight again.
Upvotes: 2
Views: 177
Reputation: 6398
As you need vote partial to be rendered on each book and only in a single view, so what you can do is:
<%= render partial: "books/book", collection: @upvoted_books, locals: { vote: true } %>
Now in your partial book write down:
if vote
<%= render partial: "votes/vote", locals: {category: book.category, book: upvoted } %>
end
And make sure from rest of the places where you are rendering book
partial pass locals: { vote: false }
or else it will throw error. Or what you can do in the partial is:
vote ||= false
Or instead of using if vote
you can use if defined?(vote)
, so there would be no burden to pass it from other pages.
Also I doubt you have some wrong locals, not sure may be so correct them. But using this you can call vote
partial on a single view.
Hope this helps.
Upvotes: 1