Delete has_one id associate with has_many primary key? - ruby-on-rails

I have 2 models :
class Agency < ApplicationRecord
has_one :branding
end
class Branding < ApplicationRecord
has_many :agencies
end
when I was destroying any branding, it still keeps its key with the Agency, where I made a field branding_id.
I want something which nullifies it when any branding got to destroy in the process.
It automatically updates the agency branding_id to null.

Rails provides this option, please check below, it will update id to null in agency. for more info check this
class Branding < ApplicationRecord
has_many :agencies, dependent: :nullify
end

First of all, if Agency model has branding_id column, it should have belongs_to instead of has_one and provide optional: true option to make branding association not required:
class Agency < ApplicationRecord
belongs_to :branding, optional: true
end
Second, to do this, you should use nullify option, like this:
class Branding < ApplicationRecord
has_many :agencies, dependent: :nullify
end

Related

How to create a group of users (roomates) within one product (property) in Rails

I have a question on a platform I'm developing in Ruby on Rails 5.2.
I have an Owner model which is the owner of properties/property. The owner will post a property so that users (in this case roomates) can share the same property/house/department, etc.
I have Owners and I have Users (both tables are created using devise):
Owner.rb:
class Owner < ApplicationRecord
has_many :properties
end
User.rb:
class User < ApplicationRecord
#Theres nothing here (yet)
end
This is where the magic happens. Property.rb:
class Property < ApplicationRecord
belongs_to :owner
has_many :amenities
has_many :services
accepts_nested_attributes_for :amenities
accepts_nested_attributes_for :services
mount_uploaders :pictures, PropertypictureUploader
validates :amenities, :services, presence: true
scope :latest, -> { order created_at: :desc }
end
How can multiple users share a property? I'm aware that it will have a many-to-many association but I'm a bit confused how to connect these relationships so when the owner posts a property it will display something like:
Property available for: 3 users
And then begin to limit users until it completes the amount of users available.
This sounds like your average many to many assocation:
class User < ApplicationRecord
has_many :tenancies, foreign_key: :tenant_id
has_many :properties, through: :tenancies
end
class Tenancy < ApplicationRecord
belongs_to :tenant, class_name: 'User'
belongs_to :property
end
class Property < ApplicationRecord
has_many :tenancies
has_many :tenants, through: :tenancies
def availablity
# or whatever attribute you have that defines the maximum number
max_tenants - tenancies.count
end
end
You can restrict the number of tenants with a custom validation.
You can use a join table, called users_properties. This table will have a property_id and user_id. You'll then have the following in your properties model:
has_many :users_properties
has_many :users, through: :users_properties
Read more about it here https://guides.rubyonrails.org/association_basics.html

Rails, validate has_many through association with attribute value of children

I have three models:
class User < ApplicationRecord
has_many :game_accounts
has_many :favorite_game_accounts, through: :game_account_favorites, source: :game_account
end
class GameAccount < ApplicationRecord
belongs_to :user
has_many :favorite_users, through: :game_account_favorites, source: :user
end
class GameAccountFavorite < ApplicationRecord
belongs_to :user
belongs_to :game_account
validates_presence_of :user, :game_account
validates_uniqueness_of :user, scope: :game_account_id
end
This means that User can have his own GameAccounts and other Users can add them to favorites.
I have added scope in order to prevent one user to have multiple favorites of the same GameAccount. However, there is one problem. User can add to favorite his own GameAccount. How to prevent user adding his own GameAccount to favorites?
I'm not sure that there is any built-in Rails validation for you case, so I'd suggest writing your own custom one.
In your particular case, you can verify on GameAccountFavorite instance, that game_account.user_id isn't equal to user.id.
There's plenty of ways of performing custom validation in Rails

Rails - model belongs_to and has_one same class

I have two models, User and Request
By definition, A User can have many requests, and each Request has one assigned agent (who can be a different user)
with the base as,
class User < ActiveRecord::Base
has_many :requests
end
But there's a column in Request model, agent_id which has to be linked to User.
So how do I set the relationships the best way for,
1. User has_many requests (with column requests.user_id)
2. Request has_one user(with column requests.agent_id)
Both these on Requests table
This may be what you're looking for.
class User < ActiveRecord::Base
has_many :requests
end
class Request < ActiveRecord::Base
belongs_to :user
belongs_to :agent, class_name: 'User', foreign_key: 'agent_id'
end
You'd use the long form version of the associations. Look them up in the source code to see all the options, but for this example only one extra option needs to be specified since everything else is default.
For user
has_many :requests, foreign key: :agent_id
For request
has_one :user, foreign_key: :agent_id
It should works
class User < ActiveRecord::Base
has_many :requests
end
class Request < ActiveRecord::Base
belongs_to :agent, class_name: 'User'
end
If you want also link User with agent_id:
class User < ActiveRecord::Base
has_many :requests, foreign_key: 'agent_id'
end
The best way to establish Relationships is to follow Rails Naming Conventions.
Rename column 'agent_id' to 'user_id'.
By doing so, you can use
class User < ActiveRecord::Base
has_many :requests
end
class Request < ActiveRecord::Base
belongs_to :user
end

Versioning In Rails?

We have a user model and feature model:
#app/models/user.rb
Class User < ActiveRecord::Base
has_many :user_features
has_many :features, through: :user_features
end
#app/models/user_feature.rb
Class UserFeature < ActiveRecord::Base
belongs_to :user
belongs_to :feature
end
#app/models/feature.rb
Class Feature < ActiveRecord::Base
has_many :user_features
has_many :users, through: :user_features
end
Features can be added and removed from a user's account
The typical way to do this will be to add / remove records from the user_features collection. However, we wanted to store a "history" of all the features a user has added / removed from their account over time
My question is: how would I store the user_features & indicate which features have been added & which removed?
It's very similar to versioning I think
PaperTrail works great for versioning / tracking the history of model changes and also supports has_many :through associations.
Check out the docs and see if it's what you're looking for or if it's too much for your purposes.
You should add an active field to your UserFeatures model and scope it in your user model (not tested):
#app/models/user.rb
Class User < ActiveRecord::Base
has_many :user_features
has_many :features, through: :user_features
has_many :active_user_features, -> { where(active: true) }, class_name: 'UserFeature'
has_many :active_features, through: :active_user_features
end
For deletion of packages, you should just set the active field to false

Recording the date an object is added to a has_many collection

Users on my site each have one list, which consists of a different type of users. I'm using a has_many through relationship to do this as follows:
List.rb:
class List < ActiveRecord::Base
belongs_to :company
has_many :list_applicants
has_many :applicants, through: :list_applicants
end
Applicant.rb:
class Applicant < ActiveRecord::Base
has_many :list_applicants
has_many :lists, through: :list_applicants
end
ListApplicant.rb
class ListApplicant < ActiveRecord::Base
attr_accessible :applicant_id, :list_id
belongs_to :applicant
belongs_to :list
end
Company.rb:
class Company < ActiveRecord::Base
has_one :list
end
When a user adds another user to their list, I'd like to record the date the user is added so they can sort their list of users by date added. What is the best way to do this?
You can use the created_at field of the ListApplicant model if it has one. If not, you may add manually a similar field.
UPDATE:
You can access the field by specifying both applicant and list like this:
#applicant.list_applicants.where(list_id: #list.id).first.created_at

Resources