I have 2 classes: Posts and Comments, where posts has_many :comments and comments belongs_to post.
Each of my posts has a show page with a list of comments and I would like to paginate the comments. With the current code I have, I'm showing a list of all the comments on all the pages. So, If i have 10 comments and I want to have 2 on each page, I get 5 pages with the original 10 comments on it. Could someone shed some light?
My Code:
Posts controller:
def show
#post = Post.find(params[:id])
#comments = #post.comments.page(params[:page]).per(3)
respond_to do |format|
format.html # show.html.erb
format.json { render json: #post }
end
end
"Show" views:
<%= paginate #comments %>
<% #post.comments.each_with_index do |comments, index| %>
<tr>
<td><%= index+1 %></td>
<td><%= comment.date %></td>
<td><%= comment.text %></td>
</tr>
<% end %>
</table>
You need to use the paginated object in the view, not get them fresh from the database:
<% #comments.each_with_index do |comments, index| %>
<tr>
<td><%= index+1 %></td>
<td><%= comment.date %></td>
<td><%= comment.text %></td>
</tr>
<% end %>
This gets them fresh, unpaginated:
#post.comments
Related
Trying out ruby, i just asked a question but here's another, getting undefined method `each' for # and i tried a lot of stuff
<h1>This is the index page</h1>
<p>I need to get the new action running!</p>
<%= link_to 'My Blog', controller: 'posts' %>
</br>
<%= link_to 'New post', new_post_path %>
<h1>Listing posts</h1>
<table>
<tr>
<th>Title</th>
<th>Text</th>
</tr>
<% #posts.each do |post| %> ///<----ERROR HERE!
<tr>
<td><%= posts.title %></td>
<td><%= posts.description %></td>
<td><%= link_to 'Show', posts_path(posts) %></td>
<td><%= link_to 'Edit', edit_posts_path(posts) %></td>
</tr>
<% end %>
</table>
This is my controller:
class PostsController < ApplicationController
def index
#posts = Post.new
end
def edit
#posts = Post.find(params[:id])
end
def update
#posts = Post.find(params[:id])
if #posts.update(posts_params)
redirect_to #posts
else
render 'edit'
end
end
def new
#posts = Post.new
end
def create
#posts = Post.new(posts_params)
if #posts.save
redirect_to #post
else
render 'new'
end
end
def show
#posts = Post.find(params[:id])
end
private
def posts_params
params.require(:posts).permit(:title, :description)
end
end
I'm pretty sure i changed eveything to be matching like #posts from #post, i would appreciate if someone could help me again, i've tried looking for an answer but not getting luck, thank you
In your controller under the index do:
def index
#posts = Post.all
end
Then in your view after your each do refer to the variable as post, not posts.
<% #posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.description %></td>
<td><%= link_to 'Show', post_path(post) %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
</tr>
<% end %>
Modify the index method in your controller to the following:
def index
#posts = Post.all
end
Post.new returns a single (empty) objet, the each method expects an enumerable (array, hash, collection,...), hence the error.
Your #posts instance variable is pointing to a new post record instead of a collection of posts. You need an array to iterate over instead of a single post.
If you want to call .each on an object, that object has to be made up of a collection of data (even if the "collection" has one element).
You're calling Post.new - meaning the .each method is going to return an exception that it cannot cycle through the expected collection.
You need to do the following:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
#posts = Post.all
end
end
This should get your code working.
I am working on something that should be simple, but I am having trouble because I am new to rails.
I have a table called TimeSheet and table called Entry.
I am working in my time_sheet show view and want to iterate through the related entries on my time_sheet.
MY models are setup like this. A user has_many :time_sheet. A time sheet belongs_to :user and has_many :entries. And entries belong_to: time_sheet
My time sheet view looks like:
<% #current.each do |t| %>
<td><%= t.entries :customer_name %></td>
<td><%= t.entries :order_number %></td>
<td><%= t.entries :time_in %></td>
<td><%= t.entries :time_out %></td>
<% end %>
My controller for the time_sheet show is:
def show
if current_user
#current = current_user.time_sheets.entries
else
redirect_to new_user_session_path, notice: 'You are not logged in.'
end
I am getting strange output that looks like this for each iteration:
#<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Entry:0xb59dfcc8>
Any help will be greatly appreciated.
Because you already
#current = current_user.time_sheets.entries
and
<% #current.each do |t| %>
So the "t" is each entry of your related time_sheets. Are you sure there is another entries? Even assume the statement don't have syntax error.
<td><%= t.entries :customer_name %></td>
How about like this.
def show
if current_user
#time_sheets = current_user.time_sheets
else
redirect_to new_user_session_path, notice: 'You are not logged in.'
end
end
In view:
<% #time_sheets.each do |sheet| %>
<% sheet.entries.each do |t| %>
<td><%= t.customer_name %></td>
<td><%= t.order_number %></td>
<td><%= t.time_in %></td>
<td><%= t.time_out %></td>
<% end %>
<% end %>
I assume customer_name, order_name are the fields name in your entry table.
I am very new to Rails and Web-programming and hope you can help me out with my very first project.
I am developing a website for a Real Estate Agency.
I have 3 tables in my database (Homes: Home_ID, Home_Name, Admin_ID; Admins: Admin_ID, Admin_Name, Admin_Email; Images: Image_ID, Image_Path, Image_Name, Home_ID, Admin_ID).
All 3 tables have been created using scaffold. The image information (name, path, image_id, home_id etc) have been entered in SQLite.
I get all text information of the different houses displayed correctly on the website except the pictures.
My attempt to link it in the view/home/index.html.erb created the following error:
undefined method `image_path' for #<Home:0xb63d85e0>
I used below code:
<% #homes.each do |home| %>
<tr>
<td><%= home.name %></td>
<td><%= home.details %></td>
<td><%= home.region %></td>
<td><%= home.address %></td>
<td><%= home.price %></td>
<td><%= home.admin_id %></td>
<td><%= home.image_path %></td>
</tr>
<% end %>
</table>
It looks like that the data entered in SQLite do not sync with rails.
Do you have any idea what I have done wrong and how I can fix it?
Thank you.
I'm not positive what the relationship would be between your images and home models would be so correct me if I'm wrong, but I'm guessing that homes will have many images. Each image would belong to one home. Is this correct? If so, you will need to declare that in your models like so:
models/home.rb
has_many :images
models/image.rb
belongs_to :home
You will then need to add this to the image database:
t.integer "home_id"
You can add it by going to the command line and typing:
rails g migration AddHomeToImages home_id:integer
You should look in db/migrate/ and then the most recent migration file and make sure it looks like this:
add_column :images, :home_id, :integer
Then run:
rake db:migrate
At this point you'll only need to update your controller and views to show this association. Let me know if this helps and if so I'll help you with your controller and views.
What's happening is that you are looping through a selection of records from the Home table. Because of this, when you call
<td><%= home.image_path %></td>
it's not recognizing the attribute image_path because you don't have image_path as a column of Home table. You only have Home_ID, Home_Name, Admin_ID for your columns. You will have to look into associations between models in order to figure out how to grab the image_path for each home record. You can start here.
If you update the code later on I'll be glad to comment on it.
I think that the best solution here will be to use paperclip gem.
You can take a look at this very old railscast eoisode just to understand how it works:
http://railscasts.com/episodes/134-paperclip
And here is github repository:
https://github.com/thoughtbot/paperclip
Paperclip will help you with paths, styles and preview for your images.
Thanks Jason,
I agree that it is a bit big for newbies, but the requirements were that we do a website where we need to read and write from/to a database. We had a quick introduction to rails with partnerwork and are now on our own and a "bit" lost and running out of time.
Here is the error message I am getting:
NameError in Homes#index
undefined local variable or method `image' for
<#:0xb62f7aa4>
Extracted source (around line #20):
17: <% #homes.each do |home| %>
18: <tr>
19: <td><%= home.name %></td>
20: <td><%= image.home_id %></td>
21: <td><%= home.details %></td>
22: <td><%= home.region %></td>
23: <td><%= home.address %></td>
When I create the database tables I had an Image_ID in the homes table, but I was told that I don`t need it and that it is enough to have only Home_ID in the images table.
I understand that the error is caused because of image.home_id.
What is your opinion? Should I add the Image_ID back to the homes table in order to display all images for the respective home_id or is there another way? I would like to be able to decide which picture will be displayed as the main picture and which ones as the smaller pictures.
Here is the code I use:
models/home.rb
class Home < ActiveRecord::Base
attr_accessible :address, :admin_id, :details, :name, :price, :region
has_many :images
end
models/image.rb
class Image < ActiveRecord::Base
attr_accessible :image_description, :image_name, :image_path
belongs_to :home
end
views/homes/index.html.erb
<h1>Listing homes</h1>
<table>
<tr>
<th>Name</th>
<th>Image</th>
<th>Details</th>
<th>Region</th>
<th>Address</th>
<th>Price</th>
<th>Admin</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #homes.each do |home| %>
<tr>
<td><%= home.name %></td>
<td><%= image.home_id %></td>
<td><%= home.details %></td>
<td><%= home.region %></td>
<td><%= home.address %></td>
<td><%= home.price %></td>
<td><%= home.admin_id %></td>
<td><%= link_to 'Show', home %></td>
<td><%= link_to 'Edit', edit_home_path(home) %></td>
<td><%= link_to 'Destroy', home, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Home', new_home_path %>
views/homes/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<b>Name:</b>
<%= #home.name %>
</p>
<p>
<b>Image:</b>
<%= #image.home_id %>
</p>
<p>
<b>Details:</b>
<%= #home.details %>
</p>
<p>
<b>Region:</b>
<%= #home.region %>
</p>
<p>
<b>Address:</b>
<%= #home.address %>
</p>
<p>
<b>Price:</b>
<%= #home.price %>
</p>
<p>
<b>Admin:</b>
<%= #home.admin_id %>
</p>
<%= link_to 'Edit', edit_home_path(#home) %> |
<%= link_to 'Back', homes_path %>
views/images/_form.html.erb
<%= form_for(#image) do |f| %>
<% if #image.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#image.errors.count, "error") %> prohibited this image from being saved:</h2>
<ul>
<% #image.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :image_name %><br />
<%= f.text_field :image_name %>
</div>
<div class="field">
<%= f.label :image_path %><br />
<%= f.text_field :image_path %>
</div>
<div class="field">
<%= f.label :image_description %><br />
<%= f.text_area :image_description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
controllers/images_controller.rb
class ImagesController < ApplicationController
# GET /images
# GET /images.json
def index
#images = Image.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #images }
end
end
# GET /images/1
# GET /images/1.json
def show
#image = Image.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #image }
end
end
# GET /images/new
# GET /images/new.json
def new
#image = Image.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #image }
end
end
# GET /images/1/edit
def edit
#image = Image.find(params[:id])
end
# POST /images
# POST /images.json
def create
#image = Image.new(params[:image])
respond_to do |format|
if #image.save
format.html { redirect_to #image, notice: 'Image was successfully created.' }
format.json { render json: #image, status: :created, location: #image }
else
format.html { render action: "new" }
format.json { render json: #image.errors, status: :unprocessable_entity }
end
end
end
# PUT /images/1
# PUT /images/1.json
def update
#image = Image.find(params[:id])
respond_to do |format|
if #image.update_attributes(params[:image])
format.html { redirect_to #image, notice: 'Image was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #image.errors, status: :unprocessable_entity }
end
end
end
# DELETE /images/1
# DELETE /images/1.json
def destroy
#image = Image.find(params[:id])
#image.destroy
respond_to do |format|
format.html { redirect_to images_url }
format.json { head :no_content }
end
end
end
Thank you so much. I really appreciate your help!!!
I have two models Jobs and Questions. A job has many questions and questions belong to a job.
I've set up the resources in the model, as well as the routes. I am having an issue trying to link_to the Show method of the questions controller on the questions#index page. My rake routes say that the path should be job_question_path with the two necessary :id's being :job_id and :id , so I tried:
<td><%= link_to 'Show', job_question_path(#job, question) %></td>
and got the error:
No route matches {:action=>"show", :controller=>"questions", :job_id=>nil, :id=>#<Question id: 1, job_id: 1, question1: "sfsdfssfs", question2: "sfsdfs", question3: "sfsdf", question4: "sfsdfsf", question5: "sfsfsfs", created_at: "2011-06-21 03:25:12", updated_at: "2011-06-21 03:25:12">}
I've tried multiple other combos and nothing is seeming to work, I keep getting:
No route matches {:action=>"show", :controller=>"questions", :job_id=>nil }
or some combination of that.
The part I don't get is that I can put in the url /jobs/1/questions/1 and it takes me to the show page, so I am assuming that my questions#show methods are ok. See below for the rest of my code.
Questions#index view
<% #questions.each do |question| %>
<tr>
<td><%= question.question1 %></td>
<td><%= question.question2 %></td>
<td><%= question.question3 %></td>
<td><%= question.question4 %></td>
<td><%= question.question5 %></td>
<td><%= link_to 'Show', job_question_path(#job, question) %></td>
</tr>
<% end %>
Questions Controller
def index
#questions = Question.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #questions }
end
end
def show
#job = Job.find(params[:job_id])
#question = #job.questions.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #question }
end
end
Models
class Job < ActiveRecord::Base
has_many :questions
class Question < ActiveRecord::Base
belongs_to :job
Routes.rb
root :to => "pages#home"
resources :jobs do
resources :questions
end
get "pages/home"
get "pages/about"
get "pages/contact"
See this https://gist.github.com/1032734 for my rake routes.
Thanks for any help in advance, i've been at this for a while now and just can't figure out the solution. Please let me know if you need any more info.
may be so?
Questions#index view
<% #questions.each do |question| %>
<tr>
<td><%= question.question1 %></td>
<td><%= question.question2 %></td>
<td><%= question.question3 %></td>
<td><%= question.question4 %></td>
<td><%= question.question5 %></td>
<%= link_to 'Show', job_question_path(question.job_id, question.id) %>
</tr>
It have to work. Or haven't you 'job_id' field in Questions table ?
I'm trying to display something like this on posts/index.html.erb
Post #1
Comment #1 for Post #1
Comment #2
Post #2
Comment #1 for Post #2
etc.
It works fine if I go to /posts/1/comments/, /posts/2/comments/ etc
Since it's using the index file, there is no :post_id in the URL and it throws a nil error. The models use the appropriate have_many and belongs_to.
Here's part of routes.rb
resources :posts do
resources :comments
end
resources :posts
Here's part of my posts_controller.rb
def index
#posts = Post.all
#comments = params[:post_id][:desc]
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
end
end
Here's part of index.html.erb
<% #posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<tr><td><%= #comments %></td></tr>
<% end %>
</table>
Thanks!
Well, since comments belongs_to a given post, you just need to have a separate loop in the view to iterate over each of the comments for a given post.
So take the #comments var out of your controller and index view, and do this in the index view instead where you currently have #comments:
<% for comment in post.comments %>
<tr><td><%= comment.user_name %><%= comment.text %></td></tr>
<% end %>
I made the user_name and text attrs up of course you would use whatever is in your comment model.
ian.