I'm wondering if theres a best practice for what I'm trying to accomplish...
First we have the model categories, categories, has_many posts.
Now lets say, users add posts.
Now, I have a page, that I want to display only the current user's posts by category.
Lets say we have the following categories: A, B, and C
User 1, has posted in Categories A and B.
In my view I have something like:
#categories.each do |category|
category.name
#posts.each do |post|
if post.category_id==category.id
post content here
end
end
end
The problem with this, is I'm going to show the empty category, as well as the categories that do have content.
Is there a more efficient way of going about this? As I don't want to show the empty categories.
Best,
Elliot
UPDATE:
So I've been trying to use this code:
0}.each do |category| %>
For the most part its almost there. The issue is, it will still show an empty category if any posts have been entered in it at all (even if the current user has not input posts into that category.
So the question boils down to:
How do I make the following loop only count posts in the category from the current user?
0}.each do |category| %>
<% #categories.select {|cat| cat.posts.count > 0}.each do |category| %>
<%= category.name %><br/>
<% category.posts.select {|post| post.user == current_user}.each do |post| %>
<%= post.content %><br/>
<% end %>
<% end %>
This renders each category with any posts, then the content for each post within the category belonging to the current user. You'd probably want to do the initial selection in the controller though, to keep the view clean.
Adding to zetetic's answer, perhaps the lookup of the posts of a user in a given category would be done the opposite way. Instead of querying "All the posts for the category where the author is the current user", ask for "all the posts for the user where it is in given category"
<% #categories.select {|cat| cat.posts.count > 0}.each do |category| %>
<%= category.name %><br/>
<% current_user.posts_in_category(category).each do |post| %>
<%= post.content %><br/>
<% end %>
<% end %>
And throw a scoped search User#posts_in_category
EDIT: Probably you should also set the #categories variable already filtered from your controller, if you're not showing them somewhere else in your view. Also, if the category has no posts, it will not enter the cycle, so maybe the select is not needed.
#categories.select do |category|
category.posts.any? {|post| post.user == current_user }
end
Will filter out the categories to have only categories with posts by the current_user. I guess it would be more efficient doing this in the db, use this if you're fetching the #categories anyway.
As per my concern you need to have an intermediate table for users who publish posts for a given category that table might have following fields
user_id,post_id, category_id by this way you will be having a table which has category id's and for each category there is a post.
then you can do the following
get the distinct categories (from above table)
loop through the categories
get posts for those categories
** then you will not get any categories without posts
cheers,
sameera
Related
I have a list of product categories. I need that when I go to a category, for example "Acoustics", on the page, in addition to the products of this category, there should be the same heading "Acoustics".
When I write this code, it displays all the categories in the header, and I need different ones on each page to match the category name and one at a time, not all at once.
<% Category.all.each do |category| %>
<%= category.title %>
<% end %>
I am trying to show only post from a particular category id
I have a category section and i have my relationship between categories and post working i just want to show post a specific category id instead of calling all post.
I have tried this but it's not working.
<% #posts.each do |post| %>
<h5><td><%=link_to post.category(1).title, post %></td></h5>
<% end %>
if you want to show a post of a category id, this should help
<% Post.where(category_id: 1).each do |post| %>
where that 1 would be the category id
In your code:
<% #posts.each do |post| %>
<h5><td><%=link_to post.category(1).title, post %></td></h5>
<% end %>
...this part looks suspicious: category(1). If post belongs_to category, try this:
post.category.title
If a post has_many (or has_and_belongs_to_many) categories, try this:
post.categories.first.title
One of those two should give you what you want.
Beyond that, I'm not sure you're trying to link. You're linking to a post, but the linktext is the category title. So, if you have three posts in the category, "Recipes," all three links will say "Recipes." Are you trying to link to the post or the category? Either way, the linktext should relate to the url.
In my view I'm generating a a number of restaurant menus that are divided into menu categories and within those categories are dishes. Right now I have my template setup as so:
<% #menus.each do |menu| %>
<h2><%= menu.name %></h2>
...
<% menu.categories.each do |category| %>
<h3><%= category.name %></h3>
...
<% category.dishes.each do |dish| %>
<p><%= dish.name %></p>
...
<% end %>
<% end %>
<% end %>
I was wondering what would be best practice when it comes to nesting multiple enumerables in this fashion? Aside from inserting this code into a partial, is there a better way to accomplish this without cluttering the view. Is it fine as is? Thanks.
Apparently, the way your models are setup (Menu has_many categories, Category has_many dishes etc.), if you are to show all those information in the same view, you have no other way rather than just looping through them and show the required data in your view which is fine, IMHO. I don't see any problem with that.
Just one tip, while looping through the associated model's data, you just need to be careful that you always have the data present for the associated model attributes, otherwise you may get undefined method 'method_name' for nil:NilClass error for some of them. To avoid that problem, you can also use try. e.g.
menu.try(:name)
category.try(:name)
dish.try(:name)
etc.
That way, your view will not explode if some or any one of the associated model has no data present (i.e. nil).
I have a #minisets model and a #miniatures model. They both have_many of each other through the #contents model.
As well as the foreign keys, the #contents model also has a quantity column.
From my #minisets show view I can show the associated #miniatures with the following:
<% #miniset.miniatures.each do |miniature| %>
<%= link_to miniature.name, miniature %>
<% end %>
I want to be able to show the quantity entered for those miniatures but can't work out how to call information from the join table rather than the table it is joining.
Something like <%= miniature.content.quantity %> except that won't work. I assume the joining model must be in play for it to be supplying the joined info but how do I interact with it itself in that instance?
Figured it out.
I need to be working with the join object in the instance variable rather than the joined object.
Find the #contents which belong to this #miniset and then get the #miniature info from there. Makes much more sense.
<% #miniset.contents.where(miniset_id: #miniset).each do |content| %>
<%= link_to content.miniature.name, content.miniature %>
x<%= content.quantity %>
<% end %>
Found some very complicated answers to similar questions but this is dead simple. Hope it helps someone.
I have a model that have a column for name and a column for categories. There are a large amount of names that I would like to list by category but I haven't figured out how to do it.
Currently in the view I have
<% for car in #cars %>
<%= car.name %>
<% end %>
which just presents this huge list of that is way too unwieldy. I'm using #car = Car.find(:all) in the controller to get the selection.
=> If there a way I can create some form of dynamic table where it groups all the car records by category and makes a new column for each category instance, with a listing of all the associated cars?
=> I'm also afraid that that might be too many columns so after 5 or so columns can I start a new row?
=> Should I do all this in the controller or the view?
Can you specify some sample values for the category column?
Depending on what you have stored you may be able to do this:
Car.find(:all).group_by(&:category)
Which will put the cars into an ordered hash indexed by the different category values.
<% #car_categories.sort.each do |category, cars| %>
<h3><%= category %></h3>
<% for cart in cars %>
<p><%= interest.name %></p>
<% end %>
<% end %>