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.
Related
I have a post view where I want to display related posts but what I have now includes the current post as well.
How would I go about removing the current item from the search?
I don't know how to use where.not() or != in this situation or if they're even the best thing to use.
This is what I have in my post show view:
<% #related[#post.blog_category_id]&.each do |rel| %>
<a href="/posts/<%= rel.friendly_id %>" class="img-cont">
<%= image_tag("Index/#{rel.thumbnail_link}", :alt => "#{rel.title}", class: "soundtrack-img top-drop") %>
<div class="img-mdl wellington"><h3 class="img-txt basic"><%= rel.title %></h3></div>
</a>
<% end %>
And in my posts_controller show method:
#related = Post.friendly.all.group_by(&:blog_category_id)
#related already includes all posts, you need to remove the current post from the list or skip it in the iteration:
Exclude the current one before iterating
<% #related[#post.blog_category_id].reject { |post| post == #post }&.each do |rel| %>
or just skip the iteration if the current one is the post in question:
<% #related[#post.blog_category_id]&.each do |rel| %>
<% next if rel == #post %>
Try using .offset(1). Something like:
#related = Post.friendly.all.group_by(&:blog_category_id).offset(1)
or
#related = Post.friendly.all.group_by(&:blog_category_id).order("created_at desc").offset(1)
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.
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.
I use Devise gem for authentication.
In database I have users table and posts table in my database schema (and Post controller).
In post controller I want to find all posts assigned to specific user. I have user_id in posts table.
How to get all user's posts or how to check if specific post is assigned for SIGNED IN user.
I thought about something like this (of course is only pseudocode:
current_user.id == Post.where(params:[post_id]).user_id
So how to get current user id in Devise and how to check the current user id is the same like eg. user_id assigned to viewing post (I want to add 'edit' function when current user is post owner) and how to find all post which current user is owner.
Associations
Firstly, your user_id column in your posts table is what's known as a foreign_key
Foreign keys are used in relational database systems to give you the ability to call associative data from a single record. Simply, it means that you'll be able to use the ActiveRecord associations to call the data you require, rather than having to call it individually:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :posts
end
#app/models/post.rb
class Post < ActiveRecord::Base
belongs_to :user
end
This will give you the ability to use the following call:
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
#posts = current_user.posts
end
end
You'll be best served looking up the has_many association:
Fix
In regards to showing your posts for your users, you need to be sure that you have the correct "flow" set up. What I mean is you need some condition to know whether your user is signed in & that #posts is set:
#app/views/posts/index.html.erb
<% if #posts.present? %>
<% #posts.each do |post| %>
<%= post.title %>
<% end %>
<% end %>
Maybe this is the first time you use Devise. You can access current_user inside controllers or views. I imagine you could do something like this
In controller (posts_controller.rb):
#posts = current_user.posts
In view (posts/show.html.erb, I guess):
if current_user.id = #post.current_user
#render something here
end
Get all post which current user is owner.
#posts = Post.where(:user_id => current_user.id)
and on your view
<%-# commented : checking if #posts is empty -%>
<% if #posts.empty? %>
<span>Sorry, post is empty </span>
<% else %>
<%= #posts.each do |p| %>
<% if p.user_id == current_user.id %>
<% link_to "edit", edit_path(p) %>
<% end %>
<% end %>
<% end %>
There are many ways you could get current_user posts. I'll go the long way.
we need
an action
an action view and a partial
a route
a link_to
* action *
def my_posts
#posts = current_user.posts.all.order(created_at: 'DESC')
end
* view *
my_posts.html.erb
<% if #posts.present? %>
<%= render 'posts' posts: #posts %>
<% else %>
<h1>You don't have any posts yet! create one</h1>
<% end %>
_posts.html.erb
<%posts.each do |post| %>
<%= post.title %>
<% end %>
index.html.erb
<%= render 'posts' posts: #posts %>
route
get 'post' => 'posts#my_posts', as: :my_posts
link_to
<%= link_to 'My posts', my_posts_path %>
I may be late but someone can find it useful :)
I have a Post model which is used to store content posted by guest users, and that content is managed by an Admin user. The admin has the rights to block or unblock a particular post.
What I want to do is this:
Display all unblocked Posts to the Guest Users.
Display all Posts to the admin user.
For the first requirement, I have a model BlockedPost which has a polymorphic association with Post model. The post that will be blocked by the admin will be maintained in the BlockedPost model.
For the second requirement I have to give admin the right to block or unblock any particular content. So in my posts/index.html.erb I have done this
<% #posts.each do |post| %>
<% post.content %>
<% if post.post_blocked? %>
<td><%= link_to 'Unblock', blocked_post_path(content.id),:method => :delete%></td>
<% else %>
<td><%= link_to 'Block', create_blocked_post_path(content.id) %></td>
<% end %>
<% end %>
The post_blocked? method above is defined in the Post model:
class Post < ActiveRecord::Base
def post_blocked?
!self.blocked_posts.nil?
end
end
This works but the problem is every time the post_blocked? method is called it makes a database call.
Is there any way to stop this behavior and get the status of all posts in one database call itself?
hmm... i think you should change your models a little, because they are unconfortable a bit and there isnt any fast way to get your posts from DB,
delete BlockedPost model
and add a column to Post model (in migration)
t.boolean :blocked, :default => true
I'd do it like this:
#blocked_posts = Post.where( :blocked => false)
#unblocked_posts = Post.where( :blocked => true )
or prepare scopes in your Post model
and then in your view just display 2 lists
<% #unblocked_posts.each do |upost| %>
<%= upost.content %>
<%= link_to 'Block that post', ... %>
<% end %>
<% #blocked_posts.each do |bpost| %>
<%= bpost.content %>
<%= link_to 'Unblock', ... %>
<% end %>