0

I am trying to create a token field using the TokenInput plugin to add members (only the friends of the user creating the group) to a group.

So, I have my friendships controller code here:

class FriendshipsController < ApplicationController

 def index 

 @friend_list = @current_user.friends.map { |f| {:id => f.id, :name => f.first_name + ' ' + f.last_name}}


 respond_to do |format|
  format.html # index.html.erb
  format.json { render json: @friend_list }
 end
end

This returns an array, like below, at the url "/friendships.json":

[{"id":6,"name":"John Smith"},{"id":7,"name":"Jane Doe"}]

Then, I have my form, with the jquery for TokenInput below it:

 <%= form_for(@group) do |f| %>


<div class="field">
<%= f.label :group_name, "Name" %><br />
<%= f.text_field :group_name %>
</div>
<div class="ui_widget">
<%= f.label :member_tokens, "Members" %><br />
<%= f.text_field :member_tokens %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

<script>
$(function() {
    $('#group_member_tokens').tokenInput("/friendships.json");
});
</script>

My question is, how do I filter the array at /friendships.json? I have tried doing the following in my FriendshipsController:

friend_list = @current_user.friends.map { |f| {:id => f.id, :name => f.first_name + ' ' + f.last_name}}
@friend_list = friend_list.where("name LIKE ?", "%#{params[:q]}%")

... but this only returns an empty array at /friendships.json.

If anyone could let me know why this is returning an empty array I would greatly appreciate it.

UPDATE:

I tried doing this:

 @friend_list = @user_name.friends.where("name LIKE ?", "%#{params[:q]}%")
 @friend_list = @friend_list.map { |f| {:id => f.id, :first_name => f.first_name + ' ' + f.last_name}}

... but when I add the code ".where("name LIKE?", "%#{params[:q]}%")" to the end of @friend_list = current_user.friends, then I no longer get any autocomplete results in the TokenInput field (it returns "No Results").

When I manually enter the q param into the URL, for example "http://localhost:3000/friendships.json?q=k" ... I end up with an empty array. This is weird because a User with first_name Kevin is in my application.

Here is what is outputted on my ruby server:

Started GET "/friendships.json?q=ke" for 127.0.0.1 at 2012-09-16 19:27:53 -0400
Processing by FriendshipsController#index as JSON
Parameters: {"q"=>"ke"}
[...]
User Load (0.7ms)  SELECT "users".* FROM "users" INNER JOIN "friendships" ON "users"."id" = "friendships"."friend_id" WHERE "friendships"."user_id" = 2 AND (first_name LIKE '%ke%')
[...]

HOWEVER, I just tried typing in "evin" into the tokenInput text_field, and it found the user. For some reason the q parameter can't find the first letter of the user's first_name. Anyone have any thoughts on this?

kwyoung11
  • 968
  • 1
  • 10
  • 31

2 Answers2

1

Apparently postgresql considers a LIKE query case-sensitive, which is why the search query was not finding the capitalized first letter of the user's name. Instead, you have to use ilike with postgresql. See thread about this here: https://groups.google.com/forum/?fromgroups=#!topic/heroku/b6_dJyTXrCU

Here is the code that worked:

class FriendshipsController < ApplicationController

def index 
@friend_list = @user_name.friends.where("name ilike ?", "%#{params[:q]}%")
@friend_list = @friend_list.map { |f| {:id => f.id, :name => f.name}}
[...]
end
kwyoung11
  • 968
  • 1
  • 10
  • 31
0

From what you wrote I would expect a server error (500), not just an empty array. When you write this in your controller:

friend_list = current_user.friends.map { |f|
  {:id => f.id, :name => f.first_name + ' ' + f.last_name}
}
@friend_list = friend_list.where("name LIKE ?", "%#{params[:q]}%")

A problem will occur: First you are getting a collection of friends from the current_user and mapping it into an array. Then on the next line you call the ActiveRecord #where method on the array you created. But since the friend_list is not an ActiveRecord collection, you should get an error such as "undefined method 'where' for [...]:Array"

I think what you're trying to do is this:

@friend_list = current_user.friends.where("name LIKE ?", "%#{params[:q]}%")
@friend_list = @friend_list.map { |f|
  {:id => f.id, :name => f.first_name + ' ' + f.last_name}
}
Peter Duijnstee
  • 3,759
  • 2
  • 20
  • 30
  • Ok, yeah I tried that. But when I add the code ".where("name LIKE?", "%#{params[:q]}%")" to the end of @friend_list = current_user.friends, then I no longer get any autocomplete results in the TokenInput field (it returns "No Results"). I put an if params[:q] block around my controller code and this gave me "null" at the url /friendships.json. This makes me think that the params[:q] is not getting sent properly? On the plugin site here (http://loopj.com/jquery-tokeninput/) it says that "Your script must accept a GET parameter named q which will contain the term to search for." – kwyoung11 Sep 16 '12 at 22:59