Rails: Adding a "latest post" to blog - ruby-on-rails

Adding a "latest post" section to blog
This is my original code to show all my posts and it works great.
<% #post.each do |post| %>
<div class="col-md-4 col-sm-6 portfolio-item">
<a href="#portfolioModal6" class="portfolio-link" data-toggle="modal">
<div class="portfolio-caption">
<h4><%= link_to post.title, post %></h4>
<p class="text-muted"><%= post.created_at.strftime("%B, %d, %Y") %></p>
</div>
</a>
</div>
<% end %>
However, I also want to add a large div that shows my latest post. So I copy/paste the code above and changed the line <% #post.each do |post| %>to the following:
<% #post = Post.last do |post| %>
There was no errors, but nothing showed up either. The reason I added this code is because I saw in a tutorial where the teacher went into rails c and typed #post = Post.last and could see the last post created. However, when I go into terminal and type it, I get the error:
No command '#post' found, did you mean:
Command 'mpost' from package 'texlive-binaries' (main)
Command 'rpost' from package 'suck' (universe)
#post: command not found

You shouldn't type it on your terminal, but in the rails console. On your terminal, type rails console, when that loads up, you can then do:
post = Post.last
In order to only render for the last post, you wouldn't need the block, as such:
<% post = Post.last %>
<div class="col-md-4 col-sm-6 portfolio-item">
<a href="#portfolioModal6" class="portfolio-link" data-toggle="modal">
<div class="portfolio-caption">
<h4><%= link_to post.title, post %></h4>
<p class="text-muted"><%= post.created_at.strftime("%B, %d, %Y") %></p>
</div>
</a>
</div>
By the way, it's not best practice to handle domain objects in your view. You could have this as an instance variable in your controller, as a Facade object if you have multiple objects.

Extending #oreoluwa's answer with a little more rails conventions:
Your post object:
class Post < ActiverRecord::Base
scope :ordered, -> { order(created_at: :desc) } # or use your own column to order
end
Your Controller (where your view is where the last post should be rendered). You should not make queries in your views to keep better a better control.
class ExamplesController < ApplicationController
def show
#latest_post = Post.ordered.first
end
end
Your View
<div class="col-md-4 col-sm-6 portfolio-item">
<a href="#portfolioModal6" class="portfolio-link" data-toggle="modal">
<div class="portfolio-caption">
<h4><%= link_to #latest_post.title, #latest_post %></h4>
<p class="text-muted"><%= #latest_post.created_at.strftime("%B, %d, %Y") %></p>
</div>
</a>
</div>

Related

Rails retrieving all records in show controller

In my rails category show controller for categories I have it setup like this
def show
#categories = Category.find_by(params[:name])
end
But when I visit this controller it returns all records of products found in the category instead of single category.
Here is the code in my view controller for category
<div class="grid">
<% #categories.products.each do |product| %>
<%= link_to product_path(id: product.slug, category_name: product.category.name), class: "card" do %>
<div class="product-image">
<%= image_tag product.productpic.url if product.productpic? %>
</div>
<div class="product-text">
<h2 class="product-title"> <%= product.name %></h2>
<h3 class="product-price">£<%= product.price %></h3>
</div>
<% end %>
<% end %>
</div>
What am i doing wrong here?
First of all, for security purposes, you should never trust the params hash to retrieve records. Rails will "make the data safe" if you use a hash as your arguments. Use this code below:
def show
#category = Category.find_by(name: params[:name])
end
Second, usually on a show page, you only want to retrieve one record and therefore the variable should be named as singular. I corrected that above.
Third, it helps if you use proper indenting when posting examples. It makes it easier for us to help you.
Fourth, the line below (I changed #categories to #category) is basically saying: "Now that I have this single category, find all the products associated with it in the products table and put them into the |product| variable for iteration"
<% #category.products.each do |product| %>
I'm not sure what you want to do with the category, but if you keep this line of code, it will always show you all the products. Maybe you only want to show the most recent 3, in which case you could do something like this:
In your controller:
def show
#category = Category.find_by(name: params[:name])
#recent_products = #category.products.order(created_at: :desc).limit(3)
end
In your view:
<div class="grid">
<% #recent_products.each do |product| %>
<%= link_to product_path(id: product.slug, category_name: product.category.name), class: "card" do %>
<div class="product-image">
<%= image_tag product.productpic.url if product.productpic? %>
</div>
<div class="product-text">
<h2 class="product-title"> <%= product.name %></h2>
<h3 class="product-price">£<%= product.price %></h3>
</div>
<% end %>
<% end %>
</div>
You can do this way
in your controller you can write this code
def show
#category = Category.find_by_name(params[:name])
end
and in your view it will work
<div class="grid">
<% #category.products.each do |product|%>
// place your code what you want to display
<% end %>
</div>
I hope it would help you and still if you have any concern please let me know.

how to get key in ruby on rails .each loop

In laravel I am use to being able to access the key in a loop. In rails I cannot find answer to how to get that from the loop.
Standard loop like so
<% #subjects.each do |subject| %>
<div class="col-md-6 subjectColumn">
<div class="subjectBox subjectBox-<%= key %>">
<h2><%= subject.title.capitalize %><h2>
<p><%= subject.description %></p>
View courses<i class="fa fa-angle-right"></i></h2>
</div>
</div>
<% end %>
I want to add the integer for the key in the code above. I have tried...
<% #subjects.keys.each do |key, subject|
...and other various things I found here and elsewhere but nothing worked. The above code created an error. Most of the things I found just did not give any number. Any help with this would be greatly appreciated. I feel I probably just have not got the syntax quite correct or something.
Use with_index:
<% #subjects.each.with_index(1) do |subject, index| %>
<div class="col-md-6 subjectColumn">
<div class="subjectBox subjectBox-<%= index %>">
<h2><%= subject.title.capitalize %><h2>
<p><%= subject.description %></p>
View courses<i class="fa fa-angle-right"></i></h2>
</div>
</div>
<% end %>

Rendering only authorized (Devise) user data in Rails without excess empty space

I am trying to create a todo app that will allow the user to create lists and then "todo" items under each list. However, I want each user to only be able to see his or her lists. While I've been able to partially solve it using the current_user helper, the index page shows empty space where the other users lists are hidden.
Below please find the code for the index.html.erb page inside my todo_lists views.
<% #todo_lists.each do |todo_list| %>
<div class="index_row clearfix">
<% if todo_list.user == current_user %>
<h2 class="todo_list_title"><%= link_to todo_list.title, todo_list %></h2>
<p class="todo_list_sub_title"><%= todo_list.description %></p>
<p><%= todo_list.user.first_name %></p>
<% end %>
</div>
<% end %>
<div class="links">
<%= link_to "New Todo List", new_todo_list_path %>
</div>
Here's my repo on Github, in case you need to see more of the code: https://github.com/jramoscolon/todo
Is there a way to hide these empty spaces, as well as the non-matching todo items?
Given your current view code, you are indiscriminately emitting <div class="index_row clearfix"> elements, even when the todo_list.user does not match the current_user. Simply move the whole<div> outside the current_user check, like so:
<% #todo_lists.each do |todo_list| %>
<% if todo_list.user == current_user %>
<div class="index_row clearfix">
<h2 class="todo_list_title"><%= link_to todo_list.title, todo_list %></h2>
<p class="todo_list_sub_title"><%= todo_list.description %></p>
<p><%= todo_list.user.first_name %></p>
</div>
<% end %>
<% end %>
This way, all of those empty <div> elements aren't included on the page. This should clean up all that empty space.
If your index view is user specific than the instance variable you want should be user specific as well.
Instead of #todo_lists = ToDoList.all
Use the current_user.todo_lists functionality supplied by your has_many/belongs to

Call a method associated with partial rails

In my controller I have this method that retuns to me the list of specific books controller/books_controller
def postings
#books = Book.postings(current_user.id).order("created_at ASC")
render :partial =>'postings'
end
I have a partial in views/books/_postings.html.erb
<div class="container">
<h4>My Partial Postings</h4>
<% #books.each do |book| %>
<div class="row">
<div class="col-sm-2"><img src="<%= book.image_path %>" alt="..." class="img-responsive"/></div>
<div class="col-sm-10">
<h4 class="nomargin"><%= book.title %></h4>
<p><%= book.description %></p>
<p>Quantity: <%= book.quantity %></p>
<p>Available for: <%= book.sale_type %></p>
</div>
</div>
<hr>
<% end %>
</div>
In my routes :
resources :books do
collection do
get 'postings'
end
end
on running rake routes :
postings_books GET /books/postings(.:format) books#postings
When I use localhost:3000/books/postings I get the desired partial showing list of books .But when I want to call this partial from some other view eg from localhost:3000/dashboard/index:
<div class="tab-pane" id="postings">
<%= render 'books/postings', :collection => #books %>
</div>
I get the following error:
Showing /home/swati/867/WorkSpace2/assignment_3/app/views/books/_postings.html.erb where line #4 raised:
undefined method `each' for nil:NilClass
Extracted source (around line #4):
<div class="container">
<h4>My Partial Postings</h4>
<% #books.each do |book| %>
<div class="row">
<div class="col-sm-2"><img src="<%= book.image_path %>" alt="..." class="img-responsive"/></div>
<div class="col-sm-10">
I understand that render is just rendering the partial without calling my method postings in books_controller and my partial has no access to #books , which is nil. How can aprroach this ?
When you access dashboard/index you are actually calling index method of dashboards_controller. If you would like to render the books/postings partial there, you need to add the list of books (#books) in that controller too.
More info here: http://guides.rubyonrails.org/action_controller_overview.html

Rails 3 - Pagination with Kaminari - Show action of one controller, to browse records of another

My current setup is that a discussion has many posts. Thus, the show action of discussions shows a list of posts.
discussions/show.html.erb:
<% for post in #discussion.posts %>
<div class="post" id="<%= post.id %>">
<div class="post-content">
<div class="post-user">
<div class="name"><%= link_to post.user.username, post.user %></div>
</div>
<div class="post-body">
<%= post.content %>
</div>
</div>
</div>
<% end %>
And this is my discussions_controller show action:
def show
#forum = Forum.find_by_permalink(params[:forum_id])
#discussion = Discussion.find(params[:id])
end
Every time I attempt to add the paginate method to my view, I get a series of errors. I know I'm stepping on the wrong foot here, so where should I start to be able to get paginate working for this page?
Many thanks in advance, still somewhat new to Rails!
change
#discussion = Discussion.find(params[:id])
to
#posts = Discussion.find(params[:id]).posts.page(params[:page]).per(20)
Your view would then be
<% for post in #posts %>
Then you'd add the paginate code in the view
<%= paginate(#posts) %>

Resources