I am new to rails, just finished Michael Hartl's tutorial.
I am creating a small blog as my first app, I am looking to sort all the homepage blog posts and group them by.
example: TODAY and all today's post...below that YESTERDAY and yesterday's posts, etc.
I see there is a method called group_by but can't figure out how to implement it
Can someone help?
See many people are looking for such a solution online.
Thanks,
Adam
There's an awesome gem for this groupdate, try it out, a sample code below
Blog.group_by_day(:created_at)
https://github.com/ankane/groupdate
You can use group_by
posts = posts.group_by{|post|
case post.created_at
when 0.days.ago..1.day.ago
"Today"
when 1.day.ago..2.days.ago
"Yesterday"
when 1.week.ago..2.weeks.ago
"Last week"
when 2.weeks.ago..3.weeks.ago
"2 weeks ago"
when 1.month.ago..2.months.ago
"Last month"
else
"Older"
end
}
EDIT
Above code will return you as Hash, in view
#posts = {"Older"=>[#<Contact id: 1, name: "sontya", email: "montya#mailinator.com", comments: "hi there", created_at: "2015-03-20
16:46:52", updated_at: "2015-03-20 16:46:52">, #<Contact id: 2, name: "faruk", email: "faruk#dispostable.com", comments: "hi there", created_at:
"2015-03-23 18:17:05", updated_at: "2015-03-23 18:17:05">], "Yesterday" => [#<Contact id: 1, name: "sontya", email:
"montya#mailinator.com", comments: "hi there", created_at: "2015-03-20 16:46:52", updated_at: "2015-03-20 16:46:52">, #<Contact id: 2, name:
"faruk", email: "faruk#dispostable.com", comments: "hi there", created_at: "2015-03-23 18:17:05", updated_at: "2015-03-23 18:17:05">]}
similar to this with your data, then
in view, loop through the Hash
<% #posts.each do |k,v| %>
<tr>
<td><%=k%></td>
</tr>
<% v.each do |post| %>
<tr>
<td><%=post.name%></td>
</tr>
<% end %>
<% end %>
I think using a database level group isn't correct, because it's usually used with sum or count or something like that, if you don't use any of those functions that applies on groups you'll end up with only one post for each group, which is in your case one post for each day, I think you should just select all and group them into arrays and loop in the view
posts = Post.some_home_page_query.order(:created_at)
#grouped_posts = posts.chunk{ |x| x.created_at.to_date }
# you can replace the block passed to chunk with whatever you
# see fit for your own case
In the view you could do something like this
- #grouped_posts.each |date, posts|
= "Posts for #{date.some_formatting}"
- posts.each do |post|
= render post # or whatever you want
Related
I have a list on the webpage generated from database.
It first shows what I want : Beaf .
However after this information, some others information of the array show up automatically:
<Ingredient id: 1, name: "Beaf", groupid: 1, created_at: nil, updated_at: nil>
How can I remove it? Thank you very much!
# Instead of using
<%= #ingredients.each do |i| %>
# use
<% #ingredients.each do |i| %>
The = will output all ingredients, whereas your output should only occur in the loop itself
Not sure where to start with this so here goes.. I am building a small blog in which the date of each post is displayed, overtime there will be many blog posts per month, for which i would like to group together by the month it was published.
I want to display it like this in the view
Archives
January 2013
February 2013
March 2013
etc
When i click on a given month the idea is it will take me to all the posts that where published within that month.
So far I can group all the posts by month and year
#posts_by_month = Post.all.group_by { |post| post.created_at.strftime("%B %Y") }
In my view i then render like so
<% #posts_by_month.each do |m| %>
<%= m %>
<% end %>
Which returns this in the view
["July 2013", [#<Post id: 1, title: "Ruby News", comments: "dsfdsfdsfdsfdsfds", category_id: 1, user_id: 1, created_at: "2013-07-26 07:10:25", updated_at: "2013-07-26 07:19:27", photo_file_name: "pf-7.jpg", photo_content_type: "image/jpeg", photo_file_size: 162495, photo_updated_at: "2013-07-26 07:19:26">]]
So at the moment i have a hash where the month/year is the key and then all my posts in an array, is that correct?
All i want to display is the Month/Year and then click that month to be taken to all the posts for that month
Any help appreciated
EDIT
ok silly me, forgot my basics on key/value pairing, i have got just the date to display
<% #posts_by_month.each do |m,p| %>
<%= link_to m %>
<% end %>
Now i just need to be able to click the link to see all posts for that month
You could do
= link_to m, posts_path(:month => m)
Now in posts#index, fetch the posts based on params[:month]
if params[:month]
date = Date.parse("1 #{params[:month]}") # to get the first day of the month
#posts = Post.where(:created_at => date..date.end_of_month) # get posts for the month
else
#posts = Post.all
end
I am new on Ruby and I am trying get data from table. so when read this
<%= puts #note.inspect %> I have this this result.
[#<Note id: 1, user_id: 1, note_type: 0, text: "Barev dzez", lat: 40.2290542420142, lng: 44.420879046875, deleted: false, created_at: "2012-04-26 14:10:05", updated_at: "2012-04-26 14:10:05">]
So when I call Note.text (for instance) I got nil result. So what should I write here to get data from array?
Thanks
#note is an Array with one Note object. You need to get the element first. For example:
<%= #note.first.text %>
You are retrive record in an array so you need to call like this
<%= puts #note.first.text %>
or
<%= puts #note.last.text %> if there is only one record
But you don't specify how you are retrive records..
I can not figure out how to fix this issue!!! Please help!!
"undefined method `description' for nil:NilClass"
results with the following code:
<ul>Test Search:
<% #optsolr.each do |c| %>
<li>
<%= c.description %>
</li>
<% end %>
</ul>
When I only call "c" instead of c.description the result is:
Test Search:
" [#<Nmodel id: 44, name: nil, price: nil, expiration: "2012-02-22", category: "Life ", description: "my description text", user_id: 3, created_at: "2012-02-22 04:20:48", updated_at: "2012-02-22 04:20:48", quantity: nil>]"
My controller where i loop through a set of search parameters and search for a specific category:
#search = Nmodel.search do
fulltext o.category do
query_phrase_slop 16
end
end
#optsolr[count[ = #search.results
Results from rails debug:
---
- !!null
- !!null
- - !ruby/object:Nmodel
attributes:
id: 44
name: !!null
price: !!null
expiration: 2012-02-22
category: ! 'Life '
description: my description text
user_id: 3
created_at: 2012-02-22 04:20:48.048506000Z
updated_at: 2012-02-22 04:20:48.048506000Z
quantity: !!null
I guess from this Results from rails debug: --- - <<<<!!null >>>>>- <<<<!!null>>>>> - - <<<<!ruby/object:Nmodel attributes: id: 44.. it returning two empty record and one valid record.
Try this.
<ul>Test Search:
<% #optsolr.delete_if{|ele| ele.blank?}.each do |c| %>
<li>
<%= c.description %>
</li>
<% end %>
</ul>
One possibility...the sunspot search is returning an ID for an object that no longer exists in the database. This can happen, especially in development, if you have indexed an object and then deleted the row from the database (maybe by dropping the db?) without deleting it from Solr.
Think of these lines of code :
#boss_locations = BossLocation.order('min_level asc').all
#discovered = current_user.discovered_locations.includes(:boss_location).all
The first one gets all available boss locations. The second one, gets all the discovered user locations(user_id, boss_location_id) and also includes the boss_location object.
Now, in my view, i want to present every boss location and a message like 'Discovered' or 'Not Discovered', based on whether a boss location exists on #discovered.
Now, my question is how can i feed my view with an easy way to do that. I could just traverse both arrays, but i'm pretty sure it's not the better way. Maybe there is a nice way to map all the boss locations based on the discovered boss locations for the user. How would you do it ?
EDIT - The variables have :
#boss_locations :
=> [#<BossLocation id: 670261930, name: "Fire Swamp", location_index: 1, min_level: 5, needed_gold_to_open: 500, created_at: "2011-05-18 05:35:48", updated_at: "2011-05-18 05:35:48">, #<BossLocation id: 723149845, name: "Rabbit Remains", location_index: 3, min_level: 15, needed_gold_to_open: 3000, created_at: "2011-05-18 05:35:48", updated_at: "2011-05-18 05:35:48">, #<BossLocation id: 81327760, name: "Grateful Plains", location_index: 2, min_level: 10, needed_gold_to_open: 1200, created_at: "2011-05-18 05:35:48", updated_at: "2011-05-18 05:35:48">]
#discovered :
=> [#<DiscoveredLocation id: 736487645, user_id: 986759322, boss_location_id: 670261930, created_at: "2011-05-22 05:37:01", updated_at: "2011-05-22 05:37:01">, #<DiscoveredLocation id: 736487646, user_id: 986759322, boss_location_id: 723149845, created_at: "2011-05-22 05:37:06", updated_at: "2011-05-22 05:37:06">, #<DiscoveredLocation id: 736487647, user_id: 986759322, boss_location_id: 81327760, created_at: "2011-05-22 06:01:35", updated_at: "2011-05-22 06:01:35">]
This is a lot of logic to put in a controller or view; consider creating a discovered? method on the BossLocation model. That way you could iterate through #boss_locations and call discovered? on each:
<% #boss_locations.each do |bl| %>
<div>
<%= "#{bl.name}: #{bl.discovered?(current_user)}" %>
</div>
<% end %>
The method would probably look like this:
class BossLocation < ActiveRecord::Base
def discovered?(user)
user.discovered_locations.map(&:boss_location).include?(self)
end
end
I commented above and you seemed to like the idea, so I wrote it out.
To encapsulate your data-model better, you'll want to modify your model class.
class BossLocation < ActiveRecord::Base
has_many :discovered_locations
has_many :users, :through => :discovered_locations
def discovered_by?(user)
self.users.include?(user)
end
end
Then all you need in your controller is:
#boss_locations = BossLocation.order('min_level asc').all
And in your view:
<% #boss_locations.each do |boss_location| %>
<div>
<%= boss_location.name %>:
<%= boss_location.discovered_by?(current_user) ? 'Discovered' : 'Not Discovered' %>
</div>
<% end %>
As the objects in the two arrays are not identical, you might need to iterate in a custom way:
<% #boss_locations.each do |boss_location|
<div>
<%= boss_location.name %>:
<%= #discovered_boss_locations.inject('Not Discovered') { |result, element| result = 'Discovered' if element.boss_location_id == boss_location.id}
</div>
<% end %>