So I know where the problem is, but I'm fairly new to ROR and don't know how to work out what methods are available/which variables I should be using.
What I'm trying to do:
a user should be directed to views/relationship/edit when they press 'edit relationship'. the variables should correspond so the edit relationship page deals with an accepted, pending or requested relationship between the current_user and the person they're trying to connect to (followed)
i don't know why it's saying there is no decorator method - it was working before..
error:
NoMethodError in RelationshipsController#edit
undefined method `decorate' for nil:NilClass
Extracted source (around line #71):
# @relationship = current_user.active_relationships.find(params[:id]).decorate
@followed = User.find_by(name: params[:id])
@relationship = current_user.pending_relationships.find_by(followed_id: @followed).decorate
end
view/users/index:
<% if logged_in? %>
<ul>
<% @users.each do |user| %>
<li>
<%= user.name %>
<div id="relationship-status">
<% if current_user.following.include?(@followed) || current_user.pending_following.include?(user) || current_user.requested_following.include?(user) %>
<%= link_to "Edit Relationship", edit_relationship_path(followed_id: @followed, id: current_user.id), class: "btn btn-primary" %>
followed: <%= @followed %>
current_user: <%= current_user.id %>
relationship: <%= @relationship %>
<% else %>
<%= link_to "Add Relationship", new_relationship_path(follower_id: user.id), class: "btn btn-primary", id: 'add-relationship', data: { followed_id: user.id.to_param } %>
<% end %>
</div>
</li>
<% end %>
</ul>
<% end %>
relationships_controller:
def edit
# @followed = @relationship.followed
# @relationship = current_user.active_relationships.find(params[:id]).decorate
@followed = User.find(name: params[:id])
@relationship = current_user.pending_relationships.find_by(followed_id: @followed).decorate
end
views/relationship/edit:
<div class="page-header">
<h1>Viewing Relationship</h1>
</div>
<h3><%= @relationship.sub_message %></h3>
<div class="form-actions">
<% if @relationship.requested? %>
<%= form_for @relationship, url: accept_relationship_path(@relationship), method: :put do |form| %>
<%= submit_tag "Accept Relationship", class: 'btn btn-primary' %>
<% end %>
<% end %>
</div>
<%= form_for @relationship, url: relationship_path(@relationship), method: :delete do |form| %>
<%= submit_tag "Delete Relationship", class: 'btn btn-danger' %>
<% end %>
model/user:
class User < ActiveRecord::Base
has_one :profile, dependent: :destroy
has_many :pending_relationships, class_name: "Relationship",
foreign_key: "follower_id"
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, -> { where(relationships: { state: "accepted" } ) }, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
has_many :pending_following, -> { where(relationships: { state: "pending" } ) }, through: :pending_relationships, source: :followed
has_many :requested_following, -> { where(relationships: { state: "requested" } ) }, through: :pending_relationships, source: :followed
...
# Follows a user.
def follow(other_user)
active_relationships.create(followed_id: other_user.id)
end
# Unfollow a user.
def unfollow(other_user)
active_relationships.find_by(followed_id: other_user.id).destroy
end
# Return true if the current user is following the other user.
def following?(other_user)
following.include?(other_user)
end
def pending_following?(user)
pending_following.include?(user)
end
def requested_following?(user)
pending_following.include?(user)
end
user db table:
relationship controller:
class RelationshipsController < ApplicationController
before_action :logged_in_user, only: [:new, :create, :index, :accept, :edit, :destroy]
respond_to :html, :json
def new
if params[:followed_id]
@followed = User.find(params[:followed_id])
@active_relationship = current_user.active_relationships.new(followed: @followed)
else
flash[:danger] = "Relationship required"
end
rescue ActiveRecord::RecordNotFound
render 'public/404', status: :not_found
end
def create
if params[:relationship] && params[:relationship].has_key?(:followed_id)
@followed = User.find(params[:relationship][:followed_id])
# @followed = User.where(name: params[:relationship][:followed_id]).first
@relationship = Relationship.request(current_user, @followed)
respond_to do |format|
if @relationship.new_record?
format.html do
flash[:danger] = "There was a problem creating that relationship request"
redirect_to followed_path(@followed)
end
format.json { render json: @relationship.to_json, status: :precondition_failed }
else
format.html do
flash[:success] = "Friend request sent"
redirect_to followed_path(@followed)
end
format.json { render json: @relationship.to_json }
end
end
else
flash[:danger] = "Friend Required"
redirect_to users_path
end
end
# def create
# if params[:followed_id]
# @followed = User.find(params[:followed_id])
# current_user.follow(@followed)
# redirect_to user
# else
# flash[:danger] = "else statement"
# end
# end
def accept
@relationship = current_user.active_relationships.find(params[:id])
if @relationship.accept!
flash[:success] = "You are now connected with #{@relationship.followed.name}"
else
flash[:danger] = "That connection could not be accepted."
end
redirect_to relationships_path
end
def index
@relationships = current_user.active_relationships.all
@followed = User.find_by(name: params[:id])
end
def edit
#orig
# @followed = @relationship.followed
# @relationship = current_user.active_relationships.find(params[:id]).decorate
#2nd
# @followed = User.find_by(name: params[:id])
# @relationship = current_user.pending_relationships.find_by(followed_id: @followed).decorate
# stack
# @followed = User.find_by(id: params[:id])
# @relationship = current_user.pending_relationships.find_by(followed_id: @followed).decorate
#stack2
@followed = User.find_by(id: params[:id])
@relationship = current_user.pending_relationships.find_by(follower_id: @followed.id).decorate
end
def destroy
...
end
end
You are finding users by name but passing "ID" for the condition, so it is not able to retrieve corresponding records. Change this and Try Once:
def edit
# @followed = @relationship.followed
# @relationship = current_user.active_relationships.find(params[:id]).decorate
@followed = User.find_by(id: params[:id])
@relationship = current_user.pending_relationships.find_by(follower_id: @followed.id).decorate
end
Update:
You have specified follower_id
as foreign key for your pending relationships try the above edit method. I have updated it.