2

I have a relationship table with followed_id, follower_id, and status. I am using "has many through" in my user model to create the association. A user has many following through and is following many through a reverse relationship. The status defaults to "requested" when a user follows another user.

So then a user has a list of their followers and each has a status of "requested".

What I need in this list of followers is a link_to with a put method or a form that just finds that relationship and updates the status string to "approved". It seems like it would be pretty easy but I have been searching for days and cannot figure it out. This is what I have so far:

In the users_controller this the action to change the status from "requested" to "approved":

def activate
  @user = User.find(params[:id])
  params[:status] = {:status => 'approved'}
  @user.status = params[:user][:status]
  @user.save
  render 'show_followers'
end 

this is in the users_controller to list the followers:

def followers
 @title = "Followers"
 @user = User.find(params[:id])
 @users = @user.followers.paginate(:page => params[:page])
 render 'show_followers'
end

this is where I define status which is probably not right in user.rb model

def status
    Relationship.status.find_by_follower_id(self)
end

and this is the page where I show the followers:

      <% unless @users.empty? %>
        <% @users.each do |user| %>
        <tr>
            <td><%= image_tag user.avatar.url(:thumb) %></td>
            <td><%= user.full_name %></td>
            <td><%= user.company %></td>
            <td><%= user.approval.status %></td>
        <%end%>
            <td><%= form_for @user, url: activate_user_path(@user), :html => { :method => :put } do |f| %>
                <%= f.submit "approve" %>
                <% end %>
            </td>

        </tr>
        <%= will_paginate @users %>
        <% end %>

does anyone know how I can just update that string in Relationship table to "approved"?

Tim
  • 99
  • 1
  • 11

1 Answers1

2

I see a potential problem in your form, think it should be for user and not @user & params[:user][:status] in activate method (params[:user][:status] should be nil as it has not been defined in your method). I'd rather have a remote link alongside all followers that are to be approved, then update the status using the link, but that bit is for later.

So, the form :

<%= form_for user, url: activate_user_path(user), :html => { :method => :put } do |f| %>
  <%= f.submit "approve" %>
<% end %>

and, assuming you've access to current user, and if not, passing current user too, i.e. @user via the form.

def activate
  user = User.find(params[:id]) # user to be approved
  relationship = current_user.relationships.where(:follower_id => user).first # relationship record that has above user as follower and current user as followed
  relationship.update_attributes!(:status => 'approved')
  # redirect to users#followers passing current_user
end 
prasvin
  • 3,009
  • 23
  • 28
  • Thanks Prasvin, this worked great! I did need to pass '@user' as well. So that I can learn how this worked, why does it need to say '.first' when defining 'relationship' in 'activate' ? – Tim Mar 12 '12 at 21:57
  • Hmm... using `where` results in a Relation, precisely `ActiveRecord::Relation`. So, a Relation will have a collection of objects. Calling `.first` on it will return the first object, as we are to update the object. I think you got confused because `current_user.relationships.where(:follower_id => user)` only returns a single record (bear in mind that some other query using `where` could have fetched a number of records). But, even that single record is a Relation object. So, `.first` gives us that relationship object(i.e. of your Relationship class) we wish to update. – prasvin Mar 13 '12 at 04:04
  • As a side note, its better to refrain from certain words used by Rails. I'd personally rename your Relationship model (no sure that its used by Rails, but still confusing for me) to Interest or Support or a better name :) . I personally avoid creating models with name as Test, Template(currently used in one of my projects and needs to be renamed as clashes with ActionView::Template), Application & others... Its just a suggestion, that limits further confusion. OR if its confusing for you to rename, just stick with it. Use what works best, simple and effective for you. – prasvin Mar 13 '12 at 04:16