Rails Active Admin Many to Many relationships - ruby-on-rails

I have the following models
class Owner < ActiveRecord::Base
has_many :business_owners
has_many :businesses, :through => :business_owner
end
class Business < Active Record::Base
has_many :business_owners
has_many :businesses, :through => :business_owner
end
class BusinessOwner < ActiveRecord::Base
belongs_to :owners
belongs_to :businesses
end
I have attempted to add the BusinessOwner model to the admin dashboard:
rails generate active_admin:resource BusinessOwner
which creates a file called business_owners in app/admin/
when I attempt to view the Business Owner I receive the following error:
uninitialized constant BusinessOwner::Owners
Extracted source (around line #1):
1: render renderer_for(:index)
Can someone tell me how to use active admin with many to many relationships?

Your relationships don't look right.
On the belongs_to relationships, Rails expects you to use the singular form
class BusinessOwner < ActiveRecord::Base
belongs_to :owner
belongs_to :business
end
Likewise, you need to correctly reference the :through
has_many :businesses, :through => :business_owners
(i.e. plural owners)
It's usually worth firing up the Rails console (OR WRITING TESTS, hehe) to test this stuff before you think about ActiveAdmin ;)

Correct in bussiness table do association like this:
class Business < Active Record::Base
has_many :business_owners
has_many :oweners, :through => :business_owner
end

Related

Rails has_many through - query through the relationship

Running rails 6.0.3.2 / ruby 2.7.1
I have a has_many through-relationship that isn't behaving as expected.
My models look like this:
class Item < ApplicationRecord
has_many :item_permissions
has_many :users, :through => :item_permissions
end
class User < ApplicationRecord
has_many :item_permissions
has_many :items, :through => :item_permissions
end
class ItemPermission < ApplicationRecord
belongs_to :items
belongs_to :users
end
Now I want to retrieve all Items that a certain User has permission to:
u = User.find(1)
u.items
gives me an error:
NameError (uninitialized constant User::Items)
I can get the permission entries with
u.item_permissions
Is there any way to retrieve the items for a certain user or also the other way round receiving all users that are linked to a specific item?
The mistake is in your belongs_to declarations, in both your are using the plural word instead of the singular one to reference the associated model. Try with:
class ItemPermission < ApplicationRecord
belongs_to :item # :item instead of :items
belongs_to :user # :user instead of :users
end
More information here.

Why is an association model for a many-to-many relationship only halfway pluralized?

I have a model User and a model Group, between the two I want to create a many-to-many association with a join-table, using through.
user.rb:
class User < ActiveRecord::Base
has_many :groups_user
has_many :groups, :through => :groups_user
end
group.rb:
class Group < ActiveRecord::Base
has_many :groups_user
has_many :users, :through => :groups_user
end
groups_user.rb
class GroupsUser < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
I initially tried to do the same thing naming the joining model class GroupsUsers in groups_users.rb but I got an uninitialized constant error unless I used :class_name to specify the class name.
My question is: What is the logic behind pluralizing the first name, but not the second? The association is many-to-many so both models are on equal footing. In this case group comes first merely because of the lexical order. So why pluralize one and not the other? This makes no sense to me.
The more conventional naming approach would be:
#user.rb:
class User < ActiveRecord::Base
has_many :group_users
has_many :groups, :through => :group_users
end
#group.rb:
class Group < ActiveRecord::Base
has_many :group_users
has_many :users, :through => :group_users
end
#group_user.rb
class GroupUser < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
Conventionally, the model has the singular form. So GroupsUser, not GroupsUsers. But, an instance of the join model has only one Group and one User, So, GroupUser, not GroupsUser.
If you look at the The has_many :through Association section of the Active Record Associations guide, for instance, you will see that the join model (Appointment) is singular. This is the pattern you want to follow.
If you decide to do things unconventionally, then rails needs you to help it - for instance by requiring that you specify class_name.

Rails: ActiveRecord has_many association not working

I'm a bit new to Rails Active Record associations. I've tried to set up a relationship, but I get ActiveRecord error when I try to retrieve data. Did I associate my models incorrectly?
User has many Uploads, which has many UserGraphs:
class User < ActiveRecord::Base
has_many :uploads, through: :user_graphs
end
class Upload < ActiveRecord::Base
has_many :users, through: :user_graphs
end
class UserGraph < ActiveRecord::Base
belongs_to :user
belongs_to :upload
end
I want to get all of a user's uploads, and all of a user's graphs. The 2nd line doesn't work in rails console and gives an error
#user = User.find(1)
#uploads = #user.uploads
The error:
ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :user_graphs in model User
Extra Credit:
If Users have Uploads that have UserGraphs... shouldn't it be has_many :uploads and has_many :user_graphs, through :uploads?
Add
has_many :user_graphs
to the User and Upload classes.
The :through option defines a second association on top of this one.
You didn't tell Rails that you have a user_graphs association on User, only an uploads association. So when Rails goes to follow the user_graphs association on uploads, it can't find it.
So, you need add the user_graphs association. Your models should look like this:
class User < ActiveRecord::Base
has_many :user_graphs # <<< Add this!
has_many :uploads, through: :user_graphs
end
class Upload < ActiveRecord::Base
has_many :user_graphs # <<< Add this!
has_many :users, through: :user_graphs
end
class UserGraph < ActiveRecord::Base
belongs_to :user
belongs_to :upload
end

Multiple relationships to the same models

I'm having trouble figuring out the best way to do this. I have a User model and a Tournament model and I set up a has_many :through relation between these two models called 'followed_tournaments' so that users can follow a tournament. As such, I already have a has_many :tournaments in the User model and a has_many :users in the Tournament model so that a tournament has many followers and a user can follow many tournaments.
I'd like to set up another habtm or has_many :through relationship so that a User can be considered a "contributor" to a Tournament -- a completely separate relationship than what I already set up. I'd like a tournament to have any number of contributors and the user to contribute to many tournaments.
What's the best way to go about implementing this?
Use source or class_name
class Tournament < ActiveRecord::Base
has_many :users # ... whatever
has_many :contributions
# using class_name
has_many :contributors, :through => :contributions
# using source
has_many :contributors, :through => :contributions, :source => :user
end
class Contribution < ActiveRecord::Base
belongs_to :tournament
# using class_name
belongs_to :contributor, :class_name => 'User'
# using source
belongs_to :user
end

ActiveRecord::HasManyThroughAssociationNotFoundError in UserController#welcome

I have a many to many relationship in rails. All database tables are named accordingly and appropriately. All model files are plural and use underscore to seperate words. All naming comventions are followed by ruby and rails standards. I'm using has many through in my models like this:
has_many :users, :through => :users_posts #Post model
has_many :posts, :through => :users_posts #User model
belongs_to :users #UsersSource model
belongs_to :posts #UsersSource model
What else could this error be from?
ActiveRecord::HasManyThroughAssociationNotFoundError in UsersController#welcome
Could not find the association :users_posts in model Post
You need to define the join model as a separate association when using has_many :through:
class Post < ActiveRecord::Base
has_many :user_posts
has_many :users, :through => :user_posts
end
class User < ActiveRecord::Base
has_many :user_posts
has_many :posts, :through => :user_posts
end
class UserPost < ActiveRecord::Base
belongs_to :user # foreign_key is user_id
belongs_to :post # foreign_key is post_id
end
This works best when you need to keep data that pertains to the join model itself, or if you want to perform validations on the join separate from the other two models.
If you just want a simple join table, it's easier to use the old HABTM syntax:
class User < ActiveRecord::Base
has_and_belongs_to_many :posts
end
class Post < ActiveRecord::Base
has_and_belongs_to_many :users
end

Resources