undefined method 'each' Ruby on Rails - ruby-on-rails

Apologies in advance, I am a newbie trying to get my head around rails.
My View at the bottom works when I use:
def show
#posts = Post.all
end
However in my controller I now have:
def show
#posts = Post.find_by_category_id params[:id];
end
In my view I have
<%= #posts.each do |post| %>
<%= post.title %>
<% end %>
Some please explain why I get this error. What should I use. category_id is a foreign key on the Post table.

Look at http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find_by
Finds the first record matching the specified conditions
find_by_ will return only one post, not a collection. So you are not able to use each.

try
def show
#posts = Post.all.find_by_category_id params[:id];
end

Related

How to display the created_at in words in an article on Rails

I'm new into coding and even more new with Rails.
I'm trying to create a simple blog application, I've the articles list on the index with their title, content and created at (I used time_ago_in_words for this) however, when I try to use it inside the show view of an article it returns me an error.
With <%= #article.created_at(time_ago_in_words) %> it returns
wrong number of arguments (0 for 1..2) on the line
<span class="meta">Posted by Author <%= #article.created_at(time_ago_in_words) %></span>
With <%= #article.time_ago_in_words(article.created_at) %> it returns
undefined local variable or method `article' for #<#:0xb4ba430c> on the line
<span class="meta">Posted by Author <%= #article.time_ago_in_words(article.created_at) %></span>
My articles controller
class ArticlesController < ApplicationController
def index
#articles = Article.all.order("created_at DESC")
end
def show
#article = Article.find(params[:id])
end
def new
#article = Article.new
end
end
So I would like to know what is the properly way to display the created_at date but in words, because if I use <%= #article.created_at %> it works fine but the date it returns something like 2015-08-17 15:49:11 UTC which doesn't seems good.
Any help is highly appreciated.
The correct syntax is <%= time_ago_in_words(#article.created_at) %>

How to display all posts with all its comments - Ruby on Rails

I'm new to rails and don't know how to achieve this in rails. It might be a really stupid question. But it was not covered in the RoR Codecademy course I did and could not fint a answer elsewhere.
So I have two tables, posts and comments that have an one-to-many relationship. One post has many comments.
I want to display all post with all its comments underneath. What would be the correct way to do this?
There are two ways to do this:
First: you can do like this way in your post controller action (suppose :index) do:
def index
#posts = Post.all
end
And in your index.html.erb
<% #posts.each do |post|%>
# Your post attribute like name etc
<% post.comments.each do |comment|%>
# Your post attribute like name etc
<% end %>
<% end %>
Second: in your post controller action do:
def index
#posts = Post.all.includes(:comments)
end
And in your index.html.erb
<% #posts.each do |post|%>
# Your post attribute like name etc
<% post.comments.each do |comment|%>
# Your post attribute like name etc
<% end %>
<% end %>
Difference in above two ways is that in first one there is always a data base call when you do "post.comments" but in second there is only two data base call i.e. "Post.all.includes(:comments)", no data base call at view part, so it is up to you which way you want to use.
If a Post has_many comments then:
post = Post.find(1)
post.comments.each do |comment|
# do something with each comment here
end

will_paginate throug Individual Users Posts

I would like my users to be able to paginate through their own posts (scheduling emails). Thanks in advance to anyone who can help or steer me in the right direction!
Emails have different categories, Scheduled and Pending. I have two scopes for these in my emails model.
email.rb
scope :pending, -> { where(email_pending: true) }
scope :approved, -> { where(email_pending: false) }
I'm using devise to organize users. In my Users controller I have users#show action and I'm pulling the user's emails like this.
users_controller.rb
def show
#emails = #user.emails
end
Then in my view I list each category of email like this.
users#show
<% #user.emails.approved.each do |email| %>
-----Stuff------
<% end %>
Same thing goes for pending.
So, to paginate (using will_paginate) I tried.
users_controller.rb
#emails = #user.emails.approved.paginate(page: params[:page], per_page: 5)
and in the view I added.
users#show
<%= will_paginate #user.emails.approved %>
I also tried a few other things, but it was pretty much just guessing and trial and error... nothing worked.
Thanks again for any help! Please let me know if anyone would needs more information from me.
-Kraymer
if in the show method of your users_controller you have
#emails = #user.emails.approved.paginate(page: params[:page], per_page:
in the view you will need to use the #emails that you created
<% #emails.each do |email| %>
.....
<% end %>
<%= will_paginate #emails %>
Since by accessing #user.emails.approved you are not looking at paginated version, but the original active relation.

Kaminari & Rails pagination - undefined method `current_page'

I searched and searched, but nothing solved my problem. Here's my controller:
def show
#topic = Topic.find(params[:id])
#topic.posts = #topic.posts.page(params[:page]).per(2) # 2 for debugging
end
That functions just fine, because the topic view is reduced to two posts. However, when I add this to show.html.erb:
<%= paginate #topic.posts %>
I'm given this error:
undefined method `current_page' for #<ActiveRecord::Relation:0x69041c9b2d58>
Try with:
def show
#topic = Topic.find(params[:id])
#posts = #topic.posts.page(params[:page]).per(2)
end
And then:
<%= paginate #posts %>
If you get pagination errors in Kaminari like
undefined method `total_pages'
or
undefined method `current_page'
it is likely because the AR scope you've passed into paginate has not had the page method called on it.
Make sure you always call page on the scopes you will be passing in to paginate!
This also holds true if you have an Array that you have decorated using Kaminari.paginate_array
Bad:
<% scope = Article.all # You forgot to call page :( %>
<%= paginate(scope) # Undefined methods... %>
Good:
<% scope = Article.all.page(params[:page]) %>
<%= paginate(scope) %>
Or with a non-AR array of your own...
Bad:
<% data = Kaminari.paginate_array(my_array) # You forgot to call page :( %>
<%= paginate(data) # Undefined methods... %>
Again, this is good:
<% data = Kaminari.paginate_array(my_array).page(params[:page]) %>
<%= paginate(data) %>
Some time ago, I had a little problem with kaminari that I solved by using different variable names for each action.
Let's say in the index action you call something like:
def index
#topic = Topic.all.page(params[:page])
end
The index view works fine with <%= paginate #topic %> however if you want to use the same variable name in any other action, it throu an error like that.
def list
# don't use #topic again. choose any other variable name here
#topic_list = Topic.where(...).page(params[:page])
end
This worked for me.
Please, give a shot.

Kaminari: paginate a scoped model. Controller/View responsibility

I'm not sure i've entitled the question correctly.
In my project I have a categories controller with show action
def show
#category = Category.find params[:id]
end
And in my view I render all the posts associated with this category
#category.posts.each do |post|
link_to post.title, post
So now I want to add pagination with kaminari.
I believe I could just change #category.posts.each to #category.posts.page(params[:page]).each, but I also think that this should be responsibility of the controller. Or am I wrong? Maybe it's totally fine?
Thanks everyone.
Your show method should look like this:
def show
#posts = Category.find(params[:id]).posts.page(params[:page])
end
And in view:
#posts.each do |post|

Resources