Rails model .build set id - ruby-on-rails

In my app I have 3 model:
OrganizationType
Organization
OrganizationTypeLink
as you guess: my organization could perform more than one action, and this type of action's I want to link with organization...
And in controller I write so:
def create
#admin_organization = Organization.new(admin_organization_params)
#admin_organization.organization_type_links.build(organization_type_id: params[:organization_type_id], organization_id: #admin_organization.id)
if #admin_organization.save
....
And in model OrganizationTypeLink I see new rows in db, but how to store in Organization organization_type_link_id ? How could I store it in db?
I am new to RoR, so please give advice )
upd:
class Organization < ActiveRecord::Base
belongs_to :organization_type
has_many :organization_type_links, :dependent => :destroy
end
class OrganizationTypeLink < ActiveRecord::Base
belongs_to :organization
belongs_to :organization_type
end
class OrganizationType < ActiveRecord::Base
has_many :organizations
has_many :organization_type_links
end

how to store in Organization organization_type_link_id ? how could i store it in db?
The way you have currently defined associations in these 3 models: OrganizationType, Organization and OrganizationTypeLink
Organization has_many organization_type_links means that OrganizationTypeLink will have a foreign key named organization_id in it and not the other way round.
If you want to have organization_type_link_id in Organization then you would need to setup association as:
class Organization < ActiveRecord::Base
belongs_to :organization_type
belong_to :organization_type_link
end
class OrganizationTypeLink < ActiveRecord::Base
has_many :organizations, :dependent => :destroy
belongs_to :organization_type
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

Matching the records in ruby on rails

I have a model company, which has association, has many candidates, and belongs to company.
And I have another model key_skill, which has association, has many key_skills, and belongs to candidate.
Another model is candidate, which belongs to company, and has many key skills association.
I am trying to get the candidate whose key skills are matched to the required skill and, it should search and get the candidate who belongs to the particular company.
How can I write a query in the model for this situation?
These are the associations
company.rb
class Company < ActiveRecord::Base
has_many :candidates
end
candidate.rb
class Candidate < ActiveRecord::Base
belongs_to :company
has_many :key_skills, dependent: :destroy
accepts_nested_attributes_for :key_skills, reject_if: :all_blank,
allow_destroy: true
end
key_skill.rb
class KeySkill < ActiveRecord::Base
belongs_to :candidate
end
I think your current association condition is like this:
class Company < ApplicationRecord
has_many :candidates
end
class Candidate < ApplicationRecord
belongs_to :company
has_many :key_skills
end
class KeySkill < ApplicationRecord
belongs_to :candidate
end
For example to fetch all candidates with key_skills with ids 1,2,3 run the following query
Candidate.joins(:company, :key_skills).where("key_skills.id in (?)", [1,2,3])
Try the below:
I am assuming that key_skills table have a field skill and you want to perform search on it.
candidate = Candidate.includes(:company, :key_skills).where("key_skills.skill like ?", "%#{params[:skill]}%")
company = candidate.company

Rails associations models

I'm new to rails and I have this problem
I have three models, provider model, product model and categorie model, all models are related.
If you enter a product, you can select provider and categorie for this product.
I can not delete a provider or a categorie because they relate to product
But I can remove a product without problems
As I can manage to eliminate a provider or gategorie without affecting product?
class Categorie < ActiveRecord::Base
belongs_to :user
end
class Product < ActiveRecord::Base
belongs_to :user
belongs_to :provider
belongs_to :categorie
end
class Provider < ActiveRecord::Base
belongs_to :user
has_many :products
end
Thank!
You can use dependent: destroy on your has_many relationships so that when a provider with many products is deleted, the products are deleted as well:
class Provider < ActiveRecord::Base
has_many :products, dependent: :destroy
end
Use this gem for deleting purpose. It will soft delete entities https://github.com/rubysherpas/paranoia

Association where client orders from products. How to setup relation

I'm fiddling with rails and trying to build a small app for practicing purposes:
I want a client to order one or more products
I have a client table, a product table and last an order table which has a client_id and product_id
Now, I'm not quite sure how to set up a good relation between these table as in: client goes to product page, chooses product and saves the order.
Any help about which model should have which relation is greatly appreciated.
You can set up associations like this
Class Client < ActiveRecord::Base
has_many :orders
has_many :products,through: :orders
end
Class Product < ActiveRecord::Base
has_many :orders
has_many :clients,through: :orders
end
Class Order < ActiveRecord::Base
belongs_to :client
belongs_to :product
end
For more details,see these Guides
The association should look something like this
Class Client < ActiveRecord::Base
has_many :orders
has_many :products,through: :orders
end
Class Product < ActiveRecord::Base
has_many :orders
has_many :clients,through: :orders
end
Class Order < ActiveRecord::Base
belongs_to :client
belongs_to :product
end
You could do it like this:
#app/models/product.rb
has_many :orders
has_many :clients, through: :orders
#app/models/order.rb
belongs_to :client
has_many :order_products
has_many :products, through: :order_products
#app/models/client.rb
has_many :orders
has_many :products, through: :orders
The way to handle the creation of a new order is to set a uuid for it, and then create another join model which will handle order products. You could do this with the order model, but I felt it best to describe the basic way, as it will give you something to work from
--
uuid
We like to set uuid columns for sensitive data like orders:
#migration
add_column :orders, :uuid, :varchar, after: :id
#app/models/order.rb
before_create :set_uuid
private
def set_uuid
unless self.uuid
loop do
token = SecureRandom.hex(5)
break token unless self.class.exists?(uuid: token)
end
end
end
This means every order will have as many products as you want, accessible like this:
#user.orders.first.products #-> returns order products
--
Edit - just saw #Pavan's answer. Sorry if it's the same - hope it helps!
You have two approaches
1) set has_and_belongs_to_many between client and product model.
class Client < ActiveRecord::Base
has_and_belongs_to_many :products
end
class Product < ActiveRecord::Base
has_and_belongs_to_many :clients
end
2) set through relation between the client and production through using keyword through
class Client < ActiveRecord::Base
has_many :orders
ha_smany :products, through: orders
end
class Product < ActiveRecord::Base
has_many :orders
ha_smany :clients, through: orders
end
I am suggesting you to go with second option since you have an intermediate model.

Can a 3-way relationship be modeled this way in Rails?

A User can have many roles, but only one role per Brand.
Class User < AR::Base
has_and_belongs_to_many :roles, :join_table => "user_brand_roles"
has_and_belongs_to_many :brands, :join_table => "user_brand_roles"
end
The problem with this setup is, how do I check the brand and the role at the same time?
Or would I better off with a BrandRole model where different roles can be set up for each Brand, and then be able to assign a user to a BrandRole?
Class User < AR::Base
has_many :user_brand_roles
has_many :brand_roles, :through => :user_brand_roles
end
Class BrandRole < AR::Base
belongs_to :brand
belongs_to :role
end
Class UserBrandRole < AR::Base
belongs_to :brand_role
belongs_to :user
end
This way I could do a find on the brand for the user:
br = current_user.brand_roles.where(:brand_id => #brand.id).includes(:brand_role)
if br.blank? or br.role != ADMIN
# reject access, redirect
end
This is a new application and I'm trying to learn from past mistakes and stick to the Rails Way. Am I making any bad assumptions or design decisions here?
Assuming Roles,Brands are reference tables. You can have a single association table Responsibilities with columns user_id, role_id, brand_id.
Then you can define
Class User < AR::Base
has_many : responsibilities
has_many :roles, :through => responsibilities
has_many :brands,:through => responsibilities
end
Class Responsibility < AR::Base
belongs_to :user
has_one :role
has_one :brand
end
The you can define
Class User < AR::Base
def has_access?(brand)
responsibility = responsibilities.where(:brand => brand)
responsibility and responsibility.role == ADMIN
end
end
[Not sure if Responsibility is the term used in your domain, but use a domain term instead of calling it as user_brand_role]
This is a conceptual thing. If BrandRole is an entity for your application, then your approach should work. If BrandRole is not an entity by itself in your app, then maybe you can create a UserBrandRole model:
class User < AR::Base
has_many :user_brand_roles
end
class Brand < AR::Base
has_many :user_brand_roles
end
class Role < AR::Base
has_many :user_brand_roles
end
class UserBrandRole < AR::Base
belongs_to :user
belongs_to :brand
belongs_to :role
validates_uniqueness_of :role_id, :scope => [:user_id, :brand_id]
end

Resources