act_as_followers get all posts of user I'm following - ruby-on-rails

Im trying to get all the Posts from the the Users. I'm following using the act_as_follower gem. The User follows a profile model, and Posts belong to a User.
My User model:
acts_as_follower
My Profile model the user follows:
belongs_to :user
acts_as_followable
Post model:
belongs_to :user
My Post Controller.rb:
def follow
#profile = Profile.find(params[:id])
current_user.follow(#profile)
redirect_to :back
end
def unfollow
#profile = Profile.find(params[:id])
current_user.stop_following(#profile)
redirect_to :back
end
Im trying to implement something like this using follows_by_type method provided:
#posts = current_user.follows_by_type('Post').order("created_at DESC")
But the thing is the User follows the Profile model, but here I'm looking for a type 'Post'.
EDIT
In my index controller i'v set up the following:
#favoritePost = Post.where(user_id: current_user.all_follows.pluck(:id))
And in the view iv implemented this:
<% if user_signed_in? %>
<%#favoritePost.each do |post| %>
<%= post.title %>
<% end %>
<% end %>

The gem lets you follow multiple models and follows_by_type('Post') filters the Posts you follow.
What you're looking to do is to return the posts from the users you follow.
Controller
#posts = Post.where(user_id: current_user.all_following.pluck(:id))
View
<% #posts.each do |post| %>
<%= post.title %>
<% end %>

I worked out this solution, might not be the best, but it works as required.
In my controller i set this up:
#following = current_user.all_following
#followposts = #following.each do |f|
f.user.id
end
And in my view I have set this up:
<% #followposts.each do |f| %>
<% f.user.posts.each do |g| %>
<%= g.title %>
<% end %>
<% end %>

Related

How to write a custom function in a model in ruby on rails?

I have a User model class I have created with Devise.
I have a role field (admin=0, user=1) in my model.
Screenshot of my database:
HTML View
<% if current_user.active_admin? %>
<%= render 'layouts/admin' %>
<% else %>
<%= render 'layouts/user' %>
<% end %>
Model
def active_admin?
#your logic here
end
I want to login. If I am an admin check role is 0 render to layouts/admin else I am a user check role is 1 render to layouts/user.
How do I write code in the model to do this?
In your user.rb file:
class User < ActiveRecord::Base
def active_admin?
role == 0
end
end
In your view:
<% if current_user.active_admin? %>
<%= render 'layouts/admin' %>
<% else %>
<%= render 'layouts/user' %>
<% end %>
As Mark says, you can just check role for 0 or 1.
Any column in your database will map directly to a method on the model.
A couple of points:
If you're using Rails 5 you'll need to inherit from ApplicationRecord rather than ActiveRecord::Base.
In newer versions of Ruby you can use the #zero? method:
class User < ApplicationRecord
def active_admin?
role.zero?
end
end
No need of adding a method for checking the roles, you can directly achieve this by below change. It will return true for anything other than 0.
<% if current_user.role? %>
<%= render 'layouts/user' %>
<% else %>
<%= render 'layouts/admin' %>
<% end %>
One way can be add an method on application controller as
def after_sign_in_path_for(resource_or_scope)
if current_user.role==0
#your admin path
else
root_path
end
end
def authenticate_admin
unless (user_signed_in? and current_user.role !=0 )
redirect_to '/users/sign_in'
end
end
add to the required controller
before_filter :authenticate_admin
layout 'admin'

Rails - nested loops inside view

I'm taking up rails as a hobby but I'm still fairly new so apologies if this sounds ridiculous. I'm creating a board that can have many statuses. And each status can have many notes. However, this error comes up once I added the notes loop into the status loop on the view:
undefined method `notes' for nil:NilClass
Snippet of the boards/show.html.erb file:
<% #board.statuses.each do |status| %>
<div>
<h2><%= link_to status.name, status_url(status)%></h2>
<% #status.notes.each do |note| %>
<h2><%= link_to notes.content, note_url(note)%></h2>
<% end %>
<%= link_to 'New notes', new_note_path(#note) %>
</div>
<% end %>
I'm not sure if I'm doing something wrong within the controllers or the view though. I've been having a hard time figuring it out. I appreciate any help though!
notes_controller:
class NotesController < ApplicationController
def new
#note = Note.new
end
def create
Note.create(note_params.merge(status_id: current_user.id))
redirect_to boards_url
end
def delete
Note.find(params[:id]).destroy(note_params)
end
def update
Note.find(params[:id]).update(note_params)
end
def note_params
params.require(:note).permit(:status_id, :content)
end
end
statuses_controller:
class StatusesController < ApplicationController
def new
#status = Status.new
end
def create
Status.create(status_params.merge(board_id: current_user.id))
redirect_to :root
end
def delete
Status.find(params[:id]).destroy(status_params)
end
def update
Status.find(params[:id]).update(status_params)
end
def show
#status = Status.find(params[:id])
end
def status_params
params.require(:status).permit(:board_id, :name)
end
end
Any more information required then let me know. Thank you. :)
I'm thinking it should look more like:
<% #board.statuses.each do |status| %>
<div>
<h2><%= link_to status.name, status_url(status)%></h2>
<% status.notes.each do |note| %>
<h2><%= link_to notes.content, note_url(note)%></h2>
<% end %>
<%= link_to 'New notes', new_note_path(#note) %>
</div>
<% end %>
So that you're using the notes from the status in a given loop.
The error you're getting is because in this line <% #status.notes.each do |note| %> the view is expecting to be passed #status object from the show action in the board's controller. Since you aren't passing that #status, it's nil and nil doesn't have the method notes.
As #jvillian pointed out, it should be <% status.notes.each do |note| %> because you want to get the notes from the statuses you're iterating over with each in this line: <% #board.statuses.each do |status| %>

Acts_As_Votable can't vote on other user's posts

I am using the acts_as_votable gem and am having an issue with the voting.
I have two models - User and Post. A User is able to vote on a post.
The problem I am having is that the User is only currently able to vote on their own post, but not other users' posts.
I think this is because I have done #posts.each and then the user is only being accessed for their own posts, so they can only vote on their own posts. Or the problem is in my index method in my controller.
Index.html.erb File:
<% #posts.each do |post| %>
<div class="user-input">
<% if post.user.voted_up_on? post %>
<%= link_to unlike_post_path(post), method: :put do %>
<%= image_tag("/assets/like.png") %>
<% end %>
<% else %>
<%= link_to like_post_path(post), method: :put do %>
<%= image_tag("/assets/heart.png") %>
<% end %>
<% end %>
</div>
<% end %>
Posts_controller (relevant methods):
def index
#posts = Post.includes(:user).order("created_at DESC") #Possible issue is here??
end
def like
#post.upvote_by current_user
redirect_to :back
end
def unlike
#post.unvote_by current_user
redirect_to :back
end
Routes:
resources :posts do
member do
put "like", to: "posts#like"
put 'unlike', to: 'posts#unlike'
end
end
If someone could help me understand why a User is only able to vote on their own posts that would be great.
Got it.
Had to replace
<% if post.user.voted_up_on? post %>
with:
<% if current_user.liked? post %>
I believe it was asking if the creator of the post has voted on the post, whereas I needed just the current user to see if they have voted on the post.

View says Users is nil, but psql shows I have users

I am trying to display all the users in a view. I am using Rails 4.1.0 on Ruby 2.1.1. I am also using Heroku.
When I run psql command 'select * from users' it shows 3 users. However, in the view it seems to think my #users variable is nil
This is what my view/controller/model look like:
view: (app/views/status/index.html.erb)
<% if current_user %>
<h1>All users</h1>
<% if #users.nil? %>
users is nil
<% else %>
<% #users.each do |user| %>
<%= user %>
<% end %>
<% end %>
4
<% else %>
<%= render 'welcome' %>
<% end %>
Controller: (app/controllers/users_controller.rb)
class UsersController < ApplicationController
def index
#users = User.all
end
end
Model: (app/models/user.rb)
class User < ActiveRecord::Base
class << self
def from_omniauth(auth)
provider = auth.provider
uid = auth.uid
info = auth.info.symbolize_keys!
user = User.find_or_initialize_by(uid: uid, provider: provider)
user.name = info.name
user.avatar_url = info.image
user.profile_url = info.urls.send(provider.capitalize.to_sym)
user.save!
user
end
end
has_many :comments, dependent: :delete_all
end
Any help or or thoughts on what I am doing wrong would be great.
For displaying list of User objects set in UsersController, the index view should be in the file named app/views/users/index.html.erb.
Not app/views/status/index.html.erb as you are using.
app/views/status/index.html.erb is not connected to the UsersController; so #users is nil there, and it is correctly showing the users is nil message.

find a post against its description using rails

Friends I just want to show a single post against its description.
On my home page I have all the descriptions and when a user clicks any description then user should be redirected to its respective post.
I have two models one for Post and Descrip.
Descrip belongs_to Post
and
Post has_one Descrip
I just want to know that if user clicks on any description then on next page a post should appear related to that description.
Kindly help or suggest me how i can do that. At this time I just get all the posts when user click a description link. Any help will be highly appreciated. I have partial file which i render to my home page.This partila file have a link button as below
<% #post.reverse_each do |post| %>
<li>
<p>
<%= descrip.description %>
</p>
<%=link_to 'APPLY TO THIS JOB', descriptions_view_path, :class => 'read_more pull_rigt' %>
<% end %>
View.html.erb where i render my partial file look like this
<%= render partial: 'posts/post', locals: { post: Post.all} %>
and posts controller have two methods
def show
redirect_to post_path(Post.all) and return
end
def index
#posts = Post.all(:order => "created_at DESC")
end
and description controller have a view method
def view
#descrip = Descrip.find_by_id(params[:post_id])
#post = Post.all
end
Do this:
#config/routes.rb
root to: "descriptions#index"
resources :descriptions
#app/controllers/descriptions_controller.rb
def index
#descriptions = Description.all
end
def show
#description = Description.find params[:id]
end
#app/models/description.rb
Class Description < ActiveRecord::Base
has_one :post
end
#app/views/descriptions/index.html.erb
<% for description in #descriptions do %>
<%= link_to description.title, description_path(description.id) %>
<% end %>
#app/views/descriptions/show.html.erb
<%= #description.post %>

Resources