0

First of all, I'm fairly new to Ruby, Rails and ActiveRecord, so detailed answers would be very appreciated.

What I'm trying to achieve is a model with a Many-to-Many relation to itself. It's basically a "user has many friends (aka users)" setup.

This is what I currently have for my tables:

create_table "friendships" do |t|
  t.integer "user_id"
  t.integer "friend_id"
end

create_table "users" do |t|
  t.string   "email",
  t.string   "username",
  # etc.
end

And this is what I have for my models:

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, class_name: "User"
end

class User < ActiveRecord::Base
  has_many :friendships
  has_many :friends, through: :friendships
end

From what I've been reading, this should be giving me what I want. However, when I try to access .friends on the User object I receive an uninitialized constant Friend error. I searched for a while without luck. I really don't know how to tackle this issue, it must be something simple that I missed.

I'm using Rails 4.0.1 on Ruby 2.0.0p247 if it helps.

willtrnr
  • 431
  • 5
  • 15
  • Just to confirm, which version of Rails/ActiveRecord are you using here? – Tim Dorr Nov 25 '13 at 19:21
  • Oh yes, totally forgot, I'm using Rails 4.0, I'll edit it in. – willtrnr Nov 25 '13 at 19:23
  • Are you running 4.0.0 or 4.0.1? Just tried this exact setup with no issues under Rails 4.0.1: https://gist.github.com/timdorr/7647415 – Tim Dorr Nov 25 '13 at 19:38
  • It's 4.0.0, I'll try updating it to 4.0.1, maybe there's something wrong with Rails' files on my end. – willtrnr Nov 25 '13 at 19:41
  • I tried updating, but my project no longer loads... at all. That didn't work out too well. EDIT: Nevermind, it wasn't Rails related, it's loading fine now. – willtrnr Nov 25 '13 at 20:02
  • With the same issue? What Ruby version are you running, and what database is behind all of this? Are you running rvm or rbenv? Did you run `bundle update` to make sure all your gems are up to date? What OS are you on? Just trying to think through stuff that might contribute :) – Tim Dorr Nov 25 '13 at 22:10
  • I'm running Ruby 2.0.0p247 on Linux x64 (ArchLinux to be precise), MariaDB is behind my application and I did run `bundle update` earlier. As for RVM or rbenv, I don't remember setting either up, I assume I'm using neither if that's possible. – willtrnr Nov 25 '13 at 22:32

2 Answers2

0

I think you need to add a source option to the has_many :friends association.

Try this:

class User < ActiveRecord::Base
  has_many :friendships
  has_many :friends, through: :friendships, source: :user, class_name: "User"
end

Without this option, ActiveRecord automatically tries to find a class that matches the association name (Friend, in your case).

More details here.

Community
  • 1
  • 1
Radi
  • 696
  • 4
  • 11
  • Thanks, but unfortunately, it didn't help, I still have the same problem. – willtrnr Nov 25 '13 at 20:09
  • Does it help if you additionally add a class_name option? So the line looks like this: `has_many :friends, through: :friendships, source: :user, class_name: "User"` – Radi Nov 25 '13 at 20:10
0

I solved my problem!

In the end, this wasn't even a model or relationship issue, but rather am issue with CanCan not being able to find a Friend model due to the name of my controller.

As a quick fix, I renamed my controller FriendsController ...

class FriendsController < ApplicationController
  load_and_authorize_resource
  # ...
end

... to FriendshipsController ...

class FriendshipsController < ApplicationController
  load_and_authorize_resource
  # ...
end

... and now everything runs just fine. A different name can be supplied to CanCan, but for my case Friendships is alright.

I have to say, never did it cross my mind that the issue was right there in the controller the entire time, so I didn't share that part, maybe if I did somebody would've seen it.

willtrnr
  • 431
  • 5
  • 15