Rails 4 acts_as_follower - ruby-on-rails

I have two models
Users and Groups
a am using gem acts_as_follower
https://github.com/tcocca/acts_as_follower
User.rb
class User < ActiveRecord::Base
has_many :groups
acts_as_follower
end
and Group.rb
class Group < ActiveRecord::Base
belongs_to :user
acts_as_followable
end
links to follow and unfollow
<% if current_user %>
<% if current_user.following?(#group) %>
<h2> <%= link_to 'Unfollow', unfollow_group_path(#group), class: 'fa fa-pause' %></h2>
<% else %>
<h2> <%= link_to 'Follow', follow_group_path(#group), class: 'fa fa-play' %></h2>
<% end %>
<% else %>
<%= link_to 'Login or Register to Follow', user_session_path, class: 'fa fa-unlock' %>
<% end %>
link to administration group followers
<h5>followers
<%= p #group.followers.count %></h5>
<% #group.followers.each do |follower| %>
<%= link_to user_path(follower) do %>
<%= image_tag(follower.image.url(:show), size: "40x40") %>
<% if current_user.id == #group.user.id %>
<%= link_to 'Reject', unfollow_group_path(#group , user_id:follower.id), class: ' fa fa-close' , style: 'color:red;' %>
<% end %>
<% end %>
<% end %>
<% if current_user.id == #group.user.id %>
<h5>expect</h5>
<% #followers_block.each do |block| %>
<%= link_to user_path(block.follower) do %>
<%= image_tag(block.follower.image.url(:show), size: "40x40") %>
<%= link_to 'Accept', follow_group_path(#group , user_id:block.follower.id), class: ' fa fa-close' , style: 'color:red;' %>
<% end %>
<% end %>
<% end %>
groups_controller.rb
def follow
#group = Group.find(params[:id])
if params[:user_id] && #group.user_id == current_user.id
#user = User.find(params[:user_id])
#user_block = Follow.where(followable_id: #group, followable_type: "Group" , follower_id: #user ).first
#user_block.update_attribute(:blocked, false)
#user_block.save
redirect_to :back
else
if current_user
current_user.follow(#group)
flash[:notice] = 'are now following'
else
flash[:error] = "You must login to follow "
end
redirect_to :back
end
end
def unfollow
#group = Group.find(params[:id])
if params[:user_id] && #group.user_id == current_user.id
#user = User.find(params[:user_id])
#user.stop_following(#group)
redirect_to :back
else
if current_user
current_user.stop_following(#group)
flash[:notice] = 'You are no longer following .'
else
flash[:error] = 'You to unfollow #'
end
redirect_to :back
end
end
how to add parameter (:blocked, true) this
if current_user
current_user.follow(#group)
flash[:notice] = 'are now following'
or this
<h2> <%= link_to 'Follow', follow_group_path(#group), class: 'fa fa-play' %></h2>

solved
if current_user
follow = current_user.follow(#group)
follow.update blocked: true
flash[:notice] = 'are now following'

Related

<%= link_to 'Message me!', conversations_path(sender_id: current_user.id, recipient_id: user.id), method: 'post'%> not working

i'm new to rails and trying this for too long. I'm following tutorial to create simple chat feature for rails https://medium.com/#carly_l/how-to-build-a-simple-chat-messaging-system-in-rails-2958efcea047 , and I whenever I click new message it's not routing properly.
conversations.index.html.erb
<h3>Mailbox</h3>
<% #conversations.each do |conversation| %>
<% if conversation.sender_id == current_user.id || conversation.recipient_id == current_user.id %>
<% if conversation.sender_id == current_user.id %>
<% recipient = User.find(conversation.recipient_id) %>
<% else %>
<% recipient = User.find(conversation.sender_id) %>
<% end %>
<%= link_to recipient.first_name, conversation_messages_path(conversation)%>
<% end %>
<% end %>
</div>
</div>
All Users
<% #users.each do |user| %>
<% if user.id != current_user.id %>
<div class="item">
<%= user.first_name %> <%= link_to 'Message me!', conversations_path(sender_id: current_user.id, recipient_id: user.id), method: 'post'%>
</div>
<% end %>
<% end %>
**conversations index **
#users = User.all
#conversations = Conversation.all
conversations create function
def create
byebug
#user = current_user
if Conversation.between(params[:sender_id],params[:recipient_id]).present?
#conversation = Conversation.between(params[:sender_id], params[:recipient_id]).first
else
#conversation = Conversation.create!(conversation_params)
end
redirect_to conversation_messages_path(#conversation)
end
**routes.rb **
resources :conversations do
resources :messages
end
when I click message me path is
http://localhost:3000/conversations?recipient_id=1&sender_id=6
and does nothing.

RoR: Param is missing or the value is empty

I am getting an error when I try to update a prop(which is like an article). I can create a prop but when I go to edit it I get the following error:
This is my props controller:
class PropsController < ApplicationController
attr_accessor :user, :answer, :choice, :prop
def index
#props=Prop.all
end
def show
#prop = Prop.find(params[:id])
end
def new
#prop = Prop.new
#user = User.find(session[:user_id])
end
def edit
#prop = Prop.find(params[:id])
#user = User.find(session[:user_id])
#answer = #user.answers.update(prop_params)
end
def create
#prop = Prop.new(prop_params)
#user = User.find(session[:user_id])
#answer = Answer.new
if #prop.save
redirect_to #prop
else
render 'new'
end
end
def update
#user = User.find(session[:user_id])
#prop = Prop.find(params[:prop_id])
#answer = #user.answers.update(answer_params)
if #prop.update(prop_params)
redirect_to #prop
else
render 'edit'
end
if #answer.choice == #prop.choice
puts "hello"
#user.score += 7
#user.save
else
#user.score -= 7
#user.save
end
end
def destroy
#prop = Prop.find(params[:id])
#prop.destroy
redirect_to props_path
end
def select
#prop = Prop.find(params[:choice])
end
end
private
def prop_params
params.require(:prop).permit(:title, :text, :choice, :user_id, :id)
end
def answer_params
params.require(:answer).permit(:choice, :id, :prop_id, :user_id)
end
This is my form. It is a partials shared between the new and edit views:
<%= form_for #prop do |f| %>
<% if #prop.errors.any? %>
<div class="error_explanation">
<h2>
<%= pluralize(#prop.errors.count, "error") %>
prohibited this prop from being saved:
</h2>
<ul>
<% #prop.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<%= f.radio_button(:choice, "A") %>
<%= f.label(:choice, "The Correct Answer is A") %>
<%= f.radio_button(:choice, "B") %>
<%= f.label(:choice, "The Correct Answer is B") %>
<%= f.radio_button(:choice, "C") %>
<%= f.label(:choice, "The Answer Has Yet To Be Determined") %>
<%= f.hidden_field :user_id, :value => #user.id %>
<p>
<%= f.submit %>
</p>
<% end %>
Can you please change your update action as:
def update
#user = User.find(session[:user_id])
#prop = Prop.find(params[:prop_id].merge(:user_id => #user))
#answer = #user.answers.update(answer_params)
if #prop.update(prop_params)
redirect_to #prop
else
render 'edit'
end
if #answer.choice == #prop.choice
puts "hello"
#user.score += 7
#user.save
else
#user.score -= 7
#user.save
end
end
and your prop params as:
def prop_params
params.require(:prop).permit(:title, :text, :choice, :id)
end
This helps in sending the user_id into the prop table by using merge method. Try this I hope this could resolve your issue and make sure you change your create action to send the user_id into prop table.

Having problems setting a delete route

Took me a while but finally was able to have a user_id and friend_id associate with each other through friendships model. The problem I'm having is:
When clicking "add friend"
<% #users.each do |user| %>
<% if user.user_name != current_user.user_name %>
<% if #friendshiplink.nil? %>
<%= user.user_name %>
<%= link_to "Add Friend", friendships_path(friend_id: user.id), method: :post %>
<% else %>
<%= link_to(
("Unfollow"),
"/friendships/#{ #friendship.id }",
method: :delete ) %>
<% end %>
<% end %>
<% end %>
I get in respond is:
undefined method `id' for nil:NilClass
Extracted source (around line #86):
<% else %>
<%= link_to(
("Unfollow"),
"/friendships/#{ #friendship.id }",
method: :delete ) %>
<% end %>
<% end %>
Please let me know if I'm missing any code in order to further understand what might be the issue
Rake Routes
friendships POST /friendships(.:format) friendships#create
friendship DELETE /friendships/:id(.:format) friendships#destroy
Friendship Controller
class FriendshipsController < ApplicationController
def create
# #friendship = current_user.friendships.build
# #friendship.friend_id = params[:friend_id]
# #friendship.user_id = current_user.id
#friendship = current_user.friendships.build(friend_id: params[:friend_id])
if #friendship.save
flash[:notice] = "Added friend."
redirect_to "/users/#{ params[:friend_id] }"
else
flash[:notice] = "Unable to add friend"
redirect_to root_url
end
end
def destroy
#friendship = current_user.friendships.find(params[:id])
#friendship.destroy
flash[:notice] = "Removed friendship."
redirect_to current_user
end
private
def friendship_params
params.require(:friendship).permit(:user_id, :friend_id)
end
end
User Controller
def index
#user = User.new
#users = User.all
if current_user
#leaders = #current_user.leaders
end
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
cookies[:user_id] = #user.id
flash[:notice] = "Successfully Registerd"
redirect_to "/"
else
flash[:alert] = #user.errors.full_messages
redirect_to "/"
end
end
def new
#user = User.new
end
def edit
#user = User.friendly.find(params[:id])
current_user
end
def show
#users = User.all
#user = User.friendly.find(params[:id])
current_user
if #current_user
#followerlink = Follower.where(leader_id: #user.id,
follower_id: #current_user.id).first
#friendshiplink = Friendship.where(friend_id: #user.id,
user_id: #current_user.id).first
end
end
def update
#user = User.friendly.find(params[:id])
if #user.update(user_params)
flash[:notice] = "You have successfully update your information"
redirect_to "/"
else
flash[:alert] = #user.errors.full_messages
redirect_to "/"
end
end
def destroy
#user = User.friendly.find(params[:id])
#user.destroy
end
private
def user_params
params.require(:user).permit(:background, :username_or_email, :first_name, :last_name, :email, :password, :user_name, :avatar, :gender, :zip_code, :birthdate)
end
Where code is in user/view
<div id="user_profile">
<div id="profile_top">
<p class="profile_logo"></p>
<nav>
<div class="profile_loginout">
<%= link_to ("LOGOUT"), "/sessions/new",method: :delete %>
</div>
<div class="profile_user-links">
<a href="/users/<%= current_user.id %>">
<% if current_user.user_name.present? %>
<%= link_to current_user.user_name, user_path(current_user) %>
<% else %>
<%= current_user.first_name %>
<% end %>
</a>
<b class="size">|</b>
Settings
<b class="size">|</b>
</div>
</nav>
</div>
<div id="profile_to">
<div class="profile_background_picture">
<%= image_tag #user.background.url(:medium) %>
</div>
<div class="profile_picture">
<%= image_tag #user.avatar.url(:medium) %>
</div>
</div>
</div>
<% if #current_user && #user.id != #current_user.id %>
<% if !#followerlink %>
<form action="/followers" method="POST">
<input type="hidden"
name="authenticity_token"
value="<%= form_authenticity_token %>">
<input type="hidden"
name="leader_id"
value=<%= #user.id %>>
<input type="submit" value="Follow" class="followlink">
</form>
<% else %>
<div class="followlink">
<%= link_to(
("Unfollow"),
"/followers/#{ #followerlink.id }",
method: :delete ) %>
</div>
<% end %>
<% end %>
<p>Username: <%= #user.user_name %></p>
<h2>Friends</h2>
<ul>
<% for friendship in #user.friendships %>
<li>
(<%= link_to "remove", friendship, method: :delete %>)
</li>
<% end %>
</ul>
<p><%= link_to "Find Friends", users_path %></p>
<h2> Users who Have Befriended you </h2>
<ul>
<% for user in #user.inverse_friends %>
<li> <%= h user.user_name %></li>
<% end %>
</ul>
<% #users.each do |user| %>
<% if user.user_name != current_user.user_name %>
<% if #friendshiplink.nil? %>
<%= user.user_name %>
<%= link_to "Add Friend", friendships_path(friend_id: user.id), method: :post %>
<% else %>
<%= link_to "Unfollow", friendships_unfollow_path(#friendship), method: :delete %>
<% end %>
<% end %>
<% end %>
Thank you for all the help or hints in solving the issue. Greatly appreciate it.
On top of my head, not sure it's working but try it...
In routes:
delete '/friendships/:id', to: 'friendships_controller#destroy', as: 'friendships_unfollow'
In view:
<%= link_to "Unfollow", friendships_unfollow_path(#friendship), method: :delete %>
It is unclear where do you get your #friendship variable.

Error is not showing using different controller

In my task show page, I have form for creating a response and the responses are displayed here as well. (Task has many responses)
views\tasks\show.html.erb
<%= simple_form_for([#task, Response.new]) do |f| %>
<%= f.input :is_comment, as: :hidden %>
<%= f.input :negotiate_pay, label: false %>
<%= f.input :comment_text, as: :text, input_html: {rows: 3}, label: false %>
<div class="row">
<div class="col-md-4 col-md-offset-8">
<%= f.button :submit %>
</div>
</div>
</div>
<% end %>
<br>
<div id="comments">
<%= render #responses %>
</div>
controllers\tasks_controller
def show
#task = Task.find(params[:id])
#responses = #task.responses.all
end
controllers\responses_controller
def create
#task = Task.find(params[:task_id])
#response = #task.responses.create(response_params)
#response.user_id = current_user.id
#response.is_comment = params[:is_comment]
#response.save
respond_to do |format|
format.html { redirect_to #task }
format.js
end
end
It is working alright but it doesn't show the errors in the form after validation and submit. How can I show the error message in response form which is in the show page of task. I am using a simple_form btw.
Help please
EDIT:
Models:
models\response.rb
belongs_to :user
belongs_to :task
has_many :subcomments
default_scope -> { order('created_at DESC') }
#VALIDATIONS
validates :comment_text, presence: true
validates :negotiate_pay, presence: true
You need to add the code that will display the errors to your form :
<%= simple_form_for([#task, Response.new]) do |f| %>
<% if #response.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#response.errors.count, "error") %> prohibited this response from being saved:</h2>
<ul>
<% #response.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
and you also need to tweak your create action in the responsesController:
def create
#task = Task.find(params[:task_id])
#response = #task.responses.build(response_params)
#response.user_id = current_user.id
#response.is_comment = params[:is_comment]
respond_to do |format|
if #response.save
format.html { redirect_to #task, notice: "response was createad" }
format.js
else
format.html { render :show }
end
end
also make sure you are displaying the errors inside your application.html.erb :
<% if flash[:error] -%>
<p class='alert alert-danger'><%=h flash[:error] %></p>
<% end -%>
<% if flash[:notice] -%>
<p class='alert alert-success'><%=h flash[:notice] %></p>
<% end -%>

Method becomes nil after an ajax response?

The following code does the following: If the user, voted up show him a delete vote form and a vote down form. If the user voted down, show him a vote up form and the delete vote form. Otherwise just show the vote up and vote down form (I omitted some of the code so the question doesn't get too long).
(scenario: user voted down):
posts_controller.rb:
def show
#post = Post.find(params[:id])
#replies = #post.replies.paginate(page: params[:page])
#reply = #post.replies.build
#vote = Vote.new
store_location
end
votes_controller.rb:
class VotesController < ApplicationController
before_filter :signed_in_user
def create
#votable = find_votable
# Destroy the vote first in case the user already voted
if already_voted?
#vote = #votable.votes.find_by_user_id(current_user.id)
#vote.destroy
end
#vote = #votable.votes.build(params[:vote])
#vote.user_id = current_user.id
#votable.save
respond_to do |format|
format.html { redirect_back }
format.js
end
end
def destroy
#votable = find_votable
#vote = #votable.votes.find_by_user_id(current_user.id)
#vote.destroy
#votable.reload
respond_to do |format|
format.html { redirect_back }
format.js
end
end
private
def find_votable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
def already_voted?
#votable.votes.exists?(:user_id => current_user.id)
end
end
posts/vote_form
<div class="vote-form">
<% if #post.votes.exists?(:user_id => current_user.id) %>
<% if #post.votes.find_by_user_id(current_user.id).polarity == -1 %>
<%= form_for ([#post, #vote]), remote: true do |f| %>
<%= f.hidden_field :polarity, value: 1 %>
<div class="form-actions">
<%= button_tag type: :submit, class: "btn btn-small vote" do %>
<i class="icon-thumbs-down"></i> Vote up
<% end %>
</div>
<% end %>
<%= form_for ([#post, #post.votes.find_by_user_id(current_user.id)]),
method: :delete,
remote: true do |f| %>
<div class="form-actions">
<%= button_tag type: :submit, class: "btn btn-small btn-primary unvote" do %>
<i class="icon-thumbs-up"></i> Vote down
<% end %>
</div>
<% end %>
<% end %>
votes/create.js:
$('#<%= #votable.class.name.downcase %>-<%= #votable.id %> .vote-form').html(
"<%= escape_javascript(render('shared/delete_vote')) %>"
);
shared/_delete_vote.html.erb:
<% if #votable.votes.find_by_user_id(current_user.id).polarity == -1 %>
<%= form_for ([#votable, #votable.votes.new]), remote: true do |f| %>
<div class="form-actions">
<%= button_tag type: :submit, class: "vote-down btn btn-small" do %>
<i class="icon-thumbs-up"></i> Vote up
<% end %>
</div>
<% end %>
<%= form_for ([#votable, #vote]), method: :delete, remote: true do |f| %>
<div class="form-actions">
<%= button_tag type: :submit, class: "vote-up btn btn-small btn-primary" do %>
<i class="icon-thumbs-up"></i> Vote down
<% end %>
</div>
<% end %>
<% end %>
So, now everything works fine, except that I get this error when I click vote down, and then vote up right after (without refreshing the page):
ActionView::Template::Error (undefined method `polarity' for nil:NilClass):
1: <% if #votable.votes.find_by_user_id(current_user.id).polarity == 1 %>
2: <%= form_for ([#votable, #vote]), method: :delete, remote: true do |f| %>
What could be the problem?
EDIT:
I realized that the line in the error message is the problem (not #votable):
<% if #votable.votes.find_by_user_id(current_user.id).polarity == 1 %>
Strange, I thought it was the same as
<% if #post.votes.find_by_user_id(current_user.id).polarity == 1 %>
I think the problem is here:
def destroy
#votable = find_votable
#vote = #votable.votes.find_by_user_id(current_user.id)
#vote.destroy
#votable.reload
respond_to do |format|
format.html { redirect_back }
format.js
end
end
You destroy the vote for current user, so it can not be found inside view:
#votable.votes.find_by_user_id(current_user.id).polarity
That's why polarity is called on nil. You should reword the logic of your vote manipulations.
EDIT:
As the easiest solution, you may replace
if #votable.votes.find_by_user_id(current_user.id).polarity == -1
with
if #votable.votes.find_by_user_id(current_user.id).blank?

Resources