display posts by month/year ruby - ruby-on-rails

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

Related

Issue with database call

I have been trying to come up with a database call that would give me everything from the choices column from the questionnaires table. I was able to iterate and list the choices themselves but they have their own index value
The code #choices = Questionnaire.select(:choices).all[0] gives me just the first one
I want the database call to be #choices = Questionnaire.select(:choices).all[i] that would allow me to access all of them regardless. I have tried loops that I can think of. If anyone out there are available please help me out. I have struggled all day on this. Thanks!
Questionnaire Controller
class QuestionnairesController < ApplicationController
def index
#questions = Questionnaire.find(params[:category_id])
#params[:category_id]= <%=category.id%>
#category = Category.find(params[:category_id])
#videos = VideoClue.find(params[:category_id])
render :show
###render :show Renders Html page
end
def choose_answer
#questions = Questionnaire.find(params[:id])
#choices = Questionnaire.select(:choices).all
render :choose_answer
end
end
end
Choose_answer.html
<h1>Congrats You Hit The Choices Page!</h1>
<%= semantic_form_for #questions.choices do |c| %>
<%= c.inputs do |e| %>
<%= c.input :answer, :as => :check_boxes , :collection => #choices%>
<% end %>
<% end %>
Seed
Questionnaire.create({question: "In that year did MTV (Music Television) premiere and what was the first music video the channel aired?",
choices:'1982 Michael Jackson Bille Jean, 1984 Madonna Like a virgin, 1981 The Buggles Video Killed The Radio Star', correct_answer:"1981 The Buggles 'Video Killed The Radio Star' ", category_id:1})
Questionnaire.create({question: "This sitcom featured four girls living under one roof. They attended the same boarding school, ran a shop together and reside in a town called Peekskill." , choices:'Designing Women, The Facts of Life, Girlfriends', correct_answer:'The Facts of Life', category_id: 2})
Questionnaire.create({question: "This martial arts film premiere in 1985 which featured a young man who studies Bruce Lee's techniques while on the search for his master. This was set in New York City." , choices:'The Last Dragon, The Karate Kid, Big Trouble in Little China', correct_answer:'The Last Dragon', category_id: 3})
Questionnaire.create({question:"This game launched in 1991 on Sega Genesis which the player's mission is to collect as many golden rings as possible", choices:'Battletoads, Sonic The Hedgehog, Jewel Master', correct_answer: "Sonic The Hedgehog", category_id:4})
Questionnaire.select('choices').all returns
[<Questionnaire:0x007fbc2c9fa728
id: nil,
choices: "1982 Michael Jackson Bille Jean, 1984 Madonna Like a virgin, 1981 The Buggles Video Killed The Radio Star">,
<Questionnaire:0x007fbc2c9fa138 id: nil, choices: "Designing Women, The Facts of Life, Girlfriends">,
<Questionnaire:0x007fbc2ca01dc0 id: nil, choices: "The Last Dragon, The Karate Kid, Big Trouble in Little China">,
<Questionnaire:0x007fbc2ca00f88 id: nil, choices: "Battletoads, Sonic The Hedgehog, Jewel Master">]
choices: '1982 Michael Jackson Bille Jean, 1984 Madonna Like a virgin,
1981 The Buggles Video Killed The Radio Star'
The first thing to think about is why do you store all the possible choices as a single string? How can you know where does the text for the first option ends and where does the second one begin?
So, your first step should be to divide a single choices-containing string to, ehm, array of choices. This can be done by
database re-engineering (switching from string to array type);
splitting initial string (but in case some of your choices contain comma, you're gonna be in a bad situation)
Questionnaire.first.choices.split(',')
# => ["1982 Michael Jackson Bille Jean", "1984 Madonna Like a virgin", "1981 The Buggles Video Killed The Radio Star"]
After doing that you should be able to iterate choices in your view (or rails console). This step differs based on which option you've chosen earlier.

How to group by day archives on rails blog?

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

Ruby on rails : some array information show up automatically

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

Creating new child in nested routes

This one is driving me crazy. I've got a nested relationship between two models in my project, and I decided I did not want it to be shallow, since the child object (years) has no meaning outside the context of the parent (festivals).
So I sort of de-shallowed the relationship wherever I could find a reference to it, but I find myself unable to access the page to create a new child object.
Here's the url as I understand it should be: /festivals/1/years/new
from routes.rb:
resources :festivals do
resources :years
end
From years_controller.rb:
# GET festivals/1/years/new
# GET festivals/1/years/new.json
def new
#festival = Festival.find(params[:festival_id])
#year = #festival.years.build
respond_to do |format|
format.html # new.html.erb
format.json { render :json => #year }
end
end
And the button users press to get to the New page (on the Show page for the parent object):
<%= link_to 'Add Year', new_festival_year_path(#festival), :class => 'btn' %>
That takes the user to the correct URL, but I get:
No route matches {:action=>"show", :controller=>"years", :festival_id=>#<Festival id: 7, name: "Improganza", founded: nil, logo: "", mission: "This is that one that people spend a lot of money t...", city: "Honolulu", state_code: "HI", country_code: "US", created_at: "2013-07-26 14:49:19", updated_at: "2013-07-26 14:49:19">}
I created a new Rails project and set up scaffolds using Akria Matsuda's nested_scaffold gem, just to compare that output with my code... the resulting files look as I've shown here. I have no idea what I might be missing.
Just for good measure, the output of my rake routes:
festival_years GET /festivals/:festival_id/years(.:format) years#index
POST /festivals/:festival_id/years(.:format) years#create
new_festival_year GET /festivals/:festival_id/years/new(.:format) years#new
edit_festival_year GET /festivals/:festival_id/years/:id/edit(.:format) years#edit
festival_year GET /festivals/:festival_id/years/:id(.:format) years#show
PUT /festivals/:festival_id/years/:id(.:format) years#update
DELETE /festivals/:festival_id/years/:id(.:format) years#destroy
festivals GET /festivals(.:format) festivals#index
POST /festivals(.:format) festivals#create
new_festival GET /festivals/new(.:format) festivals#new
edit_festival GET /festivals/:id/edit(.:format) festivals#edit
festival GET /festivals/:id(.:format) festivals#show
PUT /festivals/:id(.:format) festivals#update
DELETE /festivals/:id(.:format) festivals#destroy
GET /festivals(.:format) festivals#index
POST /festivals(.:format) festivals#create
GET /festivals/new(.:format) festivals#new
GET /festivals/:id/edit(.:format) festivals#edit
GET /festivals/:id(.:format) festivals#show
PUT /festivals/:id(.:format) festivals#update
DELETE /festivals/:id(.:format) festivals#destroy
Try this:
<%= link_to 'Add Year', new_festival_year_path(#festival.id, :class => 'btn' %>
or
<%= link_to 'Add Year', new_festival_year_path({festival_id: #festival.id}, :class => 'btn' %>
according to the error you're getting
:festival_id=>#<Festival id: 7, name: "Improganza", founded: nil, logo: "", mission: "This is that one that people spend a lot of money t...", city: "Honolulu", state_code: "HI", country_code: "US", created_at: "2013-07-26 14:49:19", updated_at: "2013-07-26 14:49:19">}
the router is getting your whole festival param as the input for :festival_id
I think you are merging together the #new and #year actions in the years_controller and that might be causing some problems.
# GET festivals/1/years/new
# GET festivals/1/years/new.json
def new
#festival = Festival.find(params[:festival_id])
#year = #festival.years.build
end
def create
#festival = Festival.find(params[:festival_id])
#year = #festival.years.create(...)
#...fill in the rest of the method...
end
You also should update your link:
<%= link_to 'Add Year', new_festival_year_path(festival_id: #festival), :class => 'btn' %>
I created a short quiz on nested resources that might be helpful.
The answer was fairly silly. In my Rails server log (which I need to train myself to pay more attention to), I saw the some lines indicating a problem in line 63 of my _form.html.erb partial.
That line was:
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
festival_year_path(#festival), :class => 'btn' %>
Oops. Why I ever decided the "Cancel" button should take you to a year (that, of course, would not exist) is beyond me. I changed it to festival_path(#festival) and it's all good.
Thanks, everyone, for your help. I'm a newcomer to StackOverflow and to Rails in general. It really makes me feel welcome that I got such quick responses!

Date selection with only one dropdown

I have a model articles with created_at
In my index view I want the user to be able to select all articles created in "October 2010, November 2010, December 2010, etc." with only one select dropdown.
Has anyone done this before?
Rails 3 (MySQL)
class Article < ActiveRecord::Base
...code here...
def self.article_months
group_by_clause = "to_char(created_at,'<your date format>')"
Article.group(group_by_clause).select("#{group_by_clause} as month, count(*) as count").order(created_at desc).all
end
...code here...
end
In your view, use select_tag or collection_select or something and render the collection above.
In my controller I did:
#startdates = ActiveRecord::Base.connection.select_rows("SELECT DISTINCT MONTH(start_date), YEAR(start_date) FROM schedules WHERE event_id IN (#{#events.map{|n| n.id}.join(',')}) ORDER BY start_date ASC;")
and in my view:
<%= select(:event, :startdate, #startdates.map{|s| ["#{t("date.month_names")[s[0].to_i]} #{s[1]}", "#{s[1]}-#{s[0]}"]}, {:selected => #startdate.to_s, :include_blank => "All"}) %>

Resources