uninitialized constant User::relationship using #blog.user.followers.build - ruby-on-rails

The below code works without error:
= form_for #blog.comments.build, :remote => true do |f|
However the below results in the error "uninitialized constant User::relationship":
= form_for #blog.user.followers.build do |f|
User model is declared as below:
class User < ActiveRecord::Base
has_many :blogs
has_many :comments
has_many :relationships, :foreign_key => "follower_id", :dependent => :destroy
has_many :reverse_relationships, :foreign_key => "followed_id",
:class_name => "relationship",
:dependent => :destroy
has_many :following, :through => :relationships, :source => :followed
has_many :followers, :through => :reverse_relationships, :source => :follower
end
Why does the first example work but not hte second?
EDIT:
Blog model:
class Blog < ActiveRecord::Base
belongs_to :user
has_many :comments
end
Relationship model:
class Relationship < ActiveRecord::Base
attr_accessible :followed_id
belongs_to :follower, :class_name => "User"
belongs_to :followed, :class_name => "User"
validates :follower_id, :presence => true
validates :followed_id, :presence => true
validate :validate_followers
def validate_followers
errors.add(:follower_id, "You cannot follow yourself") if follower_id == followed_id
end
end

If you change the :class_name option on reverse relationships to:
:class_name => 'Relationship'
do you still get the problem? It should be the correct case for a class name I believe.

Related

Rails dependent destroy not working

I have User and Organization model. User has_many :organizations and Organization has_many :users.
When I want to destroy user from db using #user.destroy I get error Key (id)=(3) is still referenced from table "organizations".
Here is my User and Organization models:
Organization.rb
class Organization < ApplicationRecord
extend FriendlyId
friendly_id :name, :use => :slugged
has_many :members, :dependent => :destroy
has_many :users, :through => :members, :dependent => :destroy
has_many :moderators, -> { where :members => { :role => 1 } }, :through => :members, :source => :user
has_many :admins, -> { where :members => { :role => 2 } }, :through => :members, :source => :user
has_many :campains, :dependent => :destroy
has_many :statuses, :as => :statusable
has_many :activities
has_many :world_members
has_many :teams
accepts_nested_attributes_for :members, :users
User.rb
class User < ApplicationRecord
extend FriendlyId
friendly_id :full_name, :use => :slugged
acts_as_voter
enum role: [:user, :moderator, :organization, :admin]
has_many :members, :class_name => "Member", :foreign_key => "user_id", :dependent => :destroy
has_many :organizations, :through => :members, :dependent => :destroy
has_many :conversations, :foreign_key => :sender_id
has_many :admin_organizations, ->{ where(members: {role: 2}) }, :through => :members, source: :organization
has_many :moderate_organizations, ->{ where(members: {role: 1}) }, :through => :members, source: :organization
has_many :member_organizations, ->{ where(members: {role: 0}) }, :through => :members, source: :organization
accepts_nested_attributes_for :members, :organizations
Member.rb
class Member < ApplicationRecord
enum role: [:member, :moderator, :admin]
belongs_to :user
belongs_to :organization
You should not have dependent_destroy for :organizations or :users, just for :members.
You do not have direct relation from organization to user, nor from user to organization.
class User < ActiveRecord::Base
has_many :members, dependent: :destroy
has_many :organizations, through: :members
end
class Organization < ActiveRecord::Base
has_many :members, dependent: :destroy
has_many :users, through: :members
end
class Member < ActiveRecord::Base
belongs_to :user
belongs_to :organization
end
As you do not want to delete all users for example from an organization, just there reference to the organization and vice verse if you delete user, you do not want to delete all organizations on which user was connected to, just the reference

Mixing Self Referencial, Many to Many and Polymorphic Relations

I'm working on some app, I have User, Post and Report models so users can report other users, or posts. So I did this:
class Report < ActiveRecord::Base
belongs_to :user
belongs_to :reportable, :polymorphic => true
...
class User < ActiveRecord::Base
has_many :reports, :dependent => :destroy
has_many :reported_users, :through => :reports, :source => :reportable, :source_type => 'User'
has_many :reported_posts, :through => :reports, :source => :reportable, :source_type => 'Post'
has_many :reports, :as => :reportable, :dependent => :destroy
...
class Post < ActiveRecord::Base
has_many :reports, :as => :reportable, :dependent => :destroy
...
And my user spec looks like:
it 'reports another user' do
#reporter = FactoryGirl.create(:user)
#reported = FactoryGirl.create(:user)
Report.create!(:user => #reporter, :reportable => #reported)
Report.count.should == 1
#reporter.reported_users.size.should == 1
end
And I get an error saying:
User reports another user
Failure/Error: #reporter.reported_users.size.should == 1
expected: 1
got: 0 (using ==)
Can't figure out whats wrong, can I use has_many :reports and has_many :reports, :as => :reportable together in a model? Also, how can I get the reporters for a user? Let's say I want to have #user.reporters to get all other users who have reported a particular user.
Changing the second has_many :reports to has_many :inverse_reports solved the problem:
class User < ActiveRecord::Base
has_many :reports, :dependent => :destroy
has_many :reported_users, :through => :reports, :source => :reportable, :source_type => 'User'
has_many :reported_posts, :through => :reports, :source => :reportable, :source_type => 'Post'
has_many :inverse_reports, :class_name => 'Report', :as => :reportable, :dependent => :destroy
Now I guess I can also get the reporters for each user like:
has_many :reporters, :through => :inverse_reports, :source => :user

multiple belongs_to relationship to three model

The situation is this way..
class Organization < ActiveRecord::Base
has_many :role_memberships
has_many :roles
has_many :users, :through => :role_memberships, :uniq => true
end
class User
has_many :role_memberships
has_many :organizations, :through => :role_memberships, :uniq => true
has_many :roles, :through => :role_memberships, :uniq => true
end
class RoleMembership < ActiveRecord::Base
belongs_to :organization
belongs_to :role
belongs_to :user
end
class Role < ActiveRecord::Base
belongs_to :organization
has_many :role_memberships
has_many :users, :through => :role_memberships, :uniq => true
end
The QUESTION is how do I populate all the three foreign-keys in rolemembership table..when I do org.users.push(u) this create a record but role_id is left out...
In this case I will probably create RoleMembership object itself, like this:
RoleMembership.create(:organization_id => org.id, :role_id => role.id, :user_id => user.id)

Nested Has Many Through Plugin and Named Scopes

I have a User Model(:name, :password, :email), and Event model(:name, :etc) and Interest model (:name) [>all singular<]
Then I created two join tables -> UsersInterests and EventsInterests; each not containing a primary key and only comprised of the user_id/interest_id and event_id/interest_id respectively. [>plural<]
My Models Use the Nested Has Many Through Plugin
user.rb => has_many :users_interests
has_many :interests, :through => :users_interests
has_many :events_interests, :through => :interests
has_many :events, :through => :events_interests
event.rb => has_many :events_interests
has_many :interests, :through => :events_interests
has_many :users_interests, :through => :interests
has_many :users, :through => :users_interests
interest.rb => has_and_belongs_to_many :users
has_and_belongs_to_many :events
events_interests.rb => belongs_to :interests
belongs_to :events
users_interests.rb => belongs_to :users
belongs_to :interests
Whew..ok So I wanted to created a named_scope of that find all the events that share interest with a particular user. Here is some code someone helped me with.
named_scope :shares_interest_with_users, lambda {|user|
{ :joins => :users_interests,
:conditions => {:users_interests => {:user_id => user}}
}}
When i run from the controller =>
#user = User.find(1)
#events = Event.shares_interest_with_user(#user)
I get the error :
uninitialized constant Event::EventsInterest
Can anyone see what i messed up?
You must have named something wrong along the way. At a glance I'd say you have a file or class named incorrectly. Remember model names MUST always be singular, both in file and class names or else Rails won't make the connection. Another source of your problem is that arguments to belongs_to must also be singular. Even if you had got things right, the HABTM relationship in interests with users would have thrown an error when you ran the named scope.
I was able to solve your error with the following models.
user.rb
class User < ActiveRecord::Base
has_many :users_interests
has_many :interests, :through => :users_interests
has_many :events_interests, :through => :interests
has_many :events, :through => :events_interests
end
users_interest.rb
class UsersInterest < ActiveRecord::Base
belongs_to :user
belongs_to :interest
end
interest.rb
class Interest < ActiveRecord::Base
has_many :users,:through => :users_interests
has_many :users_interests
has_many :events_interests
has_many :events, :through => :events_interests
end
**events_interest.rb
class EventsInterest <ActiveRecord::Base
belongs_to :interest
belongs_to :event
end
event.rb
class Event <ActiveRecord::Base
has_many :events_interests
has_many :interests, :through => :events_interests
has_many :users_interests, :through => :interests
has_many :users, :through => :users_interests
named_scope :shares_interest_with_users, lambda {|user|
{ :joins => :users_interests,
:conditions => {:users_interests => {:user_id => user}}
}
}
end

User (model) hierarchy, self-referential join

I'm trying to figure out how to have a two level user relationship.
Photographers have clients. Clients have one photographer. Both are Users.
I've got a User model that looks like this:
class User < ActiveRecord::Base
#authlogic
has_many :client_associations,
:foreign_key => 'client_id',
:class_name => 'Association',
:dependent => :destroy
has_many :clients, :through => :client_associations
has_one :photographer_association,
:foreign_key => 'photographer_id',
:class_name => 'Association',
:dependent => :destroy
has_one :photographer, :through => :photographer_association
end
And an Association model that looks like:
create_table "associations", :id => false, :force => true do |t|
t.integer "photographer_id"
t.integer "client_id"
end
class Association < ActiveRecord::Base
belongs_to :client, :class_name => 'User'
belongs_to :photographer, :class_name => 'User'
end
When I fill it with some data and fire up the console, running user.clients.all or user.photographer just gives me an empty array.
What am I doing wrong?
You should switch the foreign_keys:
has_many :client_associations,
:foreign_key => 'photographer_id',
:class_name => 'Association',
:dependent => :destroy
has_many :clients, :through => :client_associations
has_one :photographer_association,
:foreign_key => 'client_id',
:class_name => 'Association',
:dependent => :destroy
has_one :photographer, :through => :photographer_association

Resources