Cant get a random post to display on rails blog - ruby-on-rails

I've been trying to get a single random blog post to display for my rails blog on the home page. This is the code I used from another post on stackoverflow
def index
#post = Post.offset(rand(Post.count)).first
end
For Views I tried everything from #post.each do |post| to <%= #post %>. and it still is not displaying one random post.

#post = Post.offset(rand(Post.count)).first query would return a single random record from posts table so you cannot call each on it (#post.each) as it is not a collection.
To display that random post in your view, use
<%= #post.try(:field_name) %>
where replace field_name with the field from posts table that you would like to display.
For example: If you have title and body fields in posts table that you would like to display in index view, use:
<%= #post.try(:title) %>
<%= #post.try(:body) %>
using try so that if #post is nil i.e., if there are no records in posts table, you wouldn't receive any error on your page.
UPDATE
To access the attributes of each post from a collection #posts set using
#posts = Post.all
You would need to iterate over the collection as below:
<%= #posts.each do |post| %>
<%= post.try(:title) %>
<%= post.try(:body) %>
<% end %>

Related

List all posts on Show view page - Rails

I'd like to make a list of posts on the app/views/posts/show.html.erb page and sort each by id.
Similar to how all of the posts are listed on my app/views/posts/index.html.erb page using the code block below:
<% #posts.each do |post| %>
<div class="col-md-4">
<%= image_tag post.img %>
<h1><%= post.title %></h1>
<p><%= post.content %></p>
<br>
<%= link_to 'Read More', post_path(post) %>
</div>
<% end %>
When I try to use the same each do method on the show page I get an error. But this is what I currently have (it only displays an img/link to the current post):
<h1>Recent Posts</h1>
<ul>
<li>
<%= image_tag #post.img %>
<h2>
<%= link_to #post.title %>
</h2>
</li>
</ul>
Index is for displaying all the items of x.
def index
#posts = Post.all
end
So what you are doing is taking all your posts, and putting them in an array called #posts. You can iterate or enumerate over those with .each do |x|. That means go through each object in the array and show the post image, title and content.
You didn't display your show, but typically a show looks like:
def show
#post = Post.find(params[:id])
end
So you are finding the post with :id and storing that data in #post. This is only 1 object, it's not an array. That's why your .each do |x| isn't working.
There is nothing stopping you from making
def show
#posts = Post.all
end
But then you can't take advantage of rails shortcuts and are repeating yourself, which isn't good in programming. If you want two very distinct windows that use the same information, it's better to figure that out in html/css with a bit of javascript.
The show action of your PostsController is probably only setting up #post, and not #posts. You can't use .each with #post because it's an instance of Post, and not an array, or something that responds to .each. Look at how #posts is set up in the index action, and copy that to your show action.

link to last post - rails

Im trying to link_to the show action for a post.
In my controller I have:
#post = Post.all
In my view I'm trying to link it to the last post like this:
<%= link_to #post.last do %>
<%= #post.last.title %>
<% end %>
But it does not take me to the show page for that post?
Post.all loads all posts, but does not guarantee an order. You might want to use the id or the created_at value to order your list of posts:
# in your controller
#posts = Post.order(:id)
# in the view:
<%= link_to #posts.last.title, #posts.last %>
Or - if you don't need the other posts in the view - just load the lastest post:
# in the controller:
#latest_post = Post.order(:id).last
# in the view:
<%= link_to #latest_post.title, #latest_post %>
Try with below code,
<%= link_to post_path(#post.last) do %>
<%= #post.last.title %>
<% end %>
If this code not work then please find route with fire rake routes in your terminal and replace post_path with your routes
Hope this will work.

how do i display an objects attributes from a different table in rails

Apologies if my terminology is off here.
I have a model for Users. I have a model for Products. Users have many products and Products belong to Users.
I am trying to have a Users index page that shows all Users and their associated Products with links to the individual User pages. My SHOW page is operating as I expect but I don't know how to show the User's Products on the index view.
SHOW (this works)
Controller
def show
#user = User.find(params[:id])
#product = #user.products
end
View
<%= #user.name %>
<% if #user.products.any? %>
Product
<%= render #product %>
<% end %>
Product Partial (referenced above)
Serial Number: <%= product.serial %>
INDEX (this does not work)
Controller
def index
#users = User.paginate(page: params[:page])
#product = #users.product #trying to show
end
View
I am at a loss here. Anything I've thought made sense doesn't work for me.
I would like to do something like
<%= user.product.serialnumber %>
or
<%= user.product.id %>
How do I show attributes of the User's Products in a view? Why does it work in a partial in my SHOW action/view but not in my INDEX action? Do I have to use a partial?
For your index action, #users is a collection of users whereas in your show #user is a single user object.
When you say, #users.product, you are calling product on collection object and not user object. So what you have to do is, iterate #users collection in your view and call product on the object
Something like
<% #users.each do |user| %>
<%user.products.each do |product|%>
<%= user.name%>
<%= product.serialnumber%>
<%= product.id%>
<%end%>
<% end %>

Adding "Featured Posts" to my blog

I am trying to add a featured post feature to my Ruby on Rails Blog. So far I have added a featured_post column to my post table and it passes a 1 if the check box is selected and 0 if not.
Now I am attempting to pull out these posts by doing the following:
/views/posts/index.html.erb
<% #featured_post.each do |post| %>
<%= post.title %>
<% end %>
And in the posts_controller.rb I am doing the following in the index action:
#featured_post = Post.all
Obviously this brings in all the post titles which is not what I want. I am assuming I have to add something to the controller to all for this but not sure what that is.
In your post model, write this
named_scope :featured,:conditions => {:featured_post => true }
write this in your controller
#featured_posts = Post.featured
and in view use this,
<% #featured_posts.each do |post| %>
<%= post.title %>
<% end %>
now you should get all the featured posts.

Strange routing in rails render partials

I'm new to rails and thought I had finally figured out some of this routing stuff, but have been going in circles with this bit all day.
I was following a tutorial about building a twitter like service, and I've got the basics working from the tutorial, but with Mongo instead of mySql.
I've got 3 types of pages.
The home page which is showing all the posts ordered by date
The user page which is showing the posts from a specific user
The posts page which is showing posts from a users friends.
So for each page, I've done the following
1) created a method in the corresponding controller to get the correct posts
2) created a _posts.html.erb page with the display parameters, which are slightly different on each page
3) referenced the partial in the index.html.erb page for each view.
The controller entries look like this
def index
#posts = Post.all(:order => 'created_at DESC')
end
or
def posts
#posts = Post.all(:conditions => {'user_id' => params[:id]}, :order => 'created_at DESC')
end
and the partials are
<%= render :partial => #posts %>
In each view is a _posts.html.erb file, and each is slightly different
home/_posts.html.erb looks like this
<%= div_for post do %>
Posted <%= time_ago_in_words(post.created_at) %> ago
Posted By <%= post.user_id %>
<%= post.text %>
<% end %>
while posts/_post.html.erb looks like this
<%= div_for post do %>
Posted By <%= post.user_id %>
<%= post.text %>
<% if post.created_at > 52.hours.since %>
<%= distance_of_time_in_words_to_now(post.created_at) %>
<% else %>
<%= post.created_at.strftime("%c") %>
<% end %>
<% end %>
Now the strange part is that on all the pages index.html.erb, users/show.html.erb, posts/index.html.erb, the partial that is being displayed is the posts/_post.html.erb. The others are being completely ignored.
my understanding was that render :partial would take the #posts and render _posts.html.erb from the current view. But this isn't happening, as only the posts/_post.html.erb is being rendered from all views.
I've looked in the routes.rb file, but don't have anything in there that would cause this problem.
Can anybody tell me why I am not displaying the proper partials?
-----------Edited --------------------------------
The directory structure for views is as follows
views
- home
-_post.html.erb
-index.htlm.erb
- layouts
- posts
-_post.html.erb
-index.html.erb
-posts.html.erb
- sessions
- users
-_post.html.erb
-new.html.erb
-show.html.erb
I hope that helps.
"post", :collection => #posts%>
maybe rails automatically defines path to the partial when you pass only collection
You're passing the collection as the argument that rails is expecting to be the name of the partial. Your call to render should look like this
<%= render partial: "post", collection: #posts %>
This will render app/views/posts/_post.html.erb, passing the local variable post to the partial.
Additionally, (is sometimes handy) there's an iteration object that is made available to this view, partial_name_iteration, that has information about the total size of the #posts collection, and the index of the current object.

Resources