About associations - ruby-on-rails

I have 3 Models. Proprietor, Property and Renter.
I'm confuse about Renter association because in my real estate system a tenant can have several leased properties.
Maybe has_many through ? If yes. How implement this?
class Proprietor < ApplicationRecord
has_many :properties, dependent: :destroy
end
class Property < ApplicationRecord
belongs_to :proprietor
end
class Renter < ApplicationRecord
end
class CreateProprietors < ActiveRecord::Migration[5.0]
def change
create_table :proprietors do |t|
t.string :full_name
t.string :email
t.date :birthday
t.string :social_security
t.string :doc_id
t.text :address
t.string :zip_code
t.timestamps
end
end
end
class CreateProperties < ActiveRecord::Migration[5.0]
def change
create_table :properties do |t|
t.references :proprietor, foreign_key: true
t.text :address
t.string :zip_code
t.integer :rooms
t.integer :bedrooms
t.integer :bathrooms
t.integer :garage
t.string :price
t.boolean :published, defalt: false
t.timestamps
end
end
end
class CreateRenters < ActiveRecord::Migration[5.0]
def change
create_table :renters do |t|
t.string :full_name
t.string :email
t.date :birthday
t.string :social_security
t.string :doc_id
t.timestamps
end
end
end

I don't think you need a has_many through on this (unless properties can have many renters as well as renters having many properties?)
If the need is as you state in your question this should be achievable like so:
class Proprietor < ApplicationRecord
has_many :properties, dependent: :destroy
end
class Property < ApplicationRecord
belongs_to :proprietor
belongs_to :renter
end
class Renter < ApplicationRecord
has_many :properties
end
class CreateProprietors < ActiveRecord::Migration[5.0]
def change
create_table :proprietors do |t|
t.string :full_name
t.string :email
t.date :birthday
t.string :social_security
t.string :doc_id
t.text :address
t.string :zip_code
t.timestamps
end
end
end
class CreateProperties < ActiveRecord::Migration[5.0]
def change
create_table :properties do |t|
t.references :proprietor, foreign_key: true
t.references :renter, foreign_key: true
t.text :address
t.string :zip_code
t.integer :rooms
t.integer :bedrooms
t.integer :bathrooms
t.integer :garage
t.string :price
t.boolean :published, default: false
t.timestamps
end
end
end
class CreateRenters < ActiveRecord::Migration[5.0]
def change
create_table :renters do |t|
t.string :full_name
t.string :email
t.date :birthday
t.string :social_security
t.string :doc_id
t.timestamps
end
end
end

Related

How to state that belongs_to can't be null in a migration?

Is it possible to state that a belongs_to type of field can't be null? Right now I have the following migration:
class CreatePosts < ActiveRecord::Migration[6.0]
def change
create_table :posts do |t|
t.belongs_to :site
t.string :title
t.timestamps
end
end
end
The generates a table where site_id can be null.
you can add options to belongs_to, so here you can add null:false option.
class CreatePosts < ActiveRecord::Migration[6.0]
def change
create_table :posts do |t|
t.belongs_to :site, null: false
t.string :title
t.timestamps
end
end
end

Creating record that belongs to 2 seperate tables

So I am trying to create a record that is associated with 2 tables but I cannot seem to get it to work.
Parameters: {"name"=>"asdfasd", "upc"=>"243252353", "availableOn"=>"07/12/2020", "properties"=>[{"name"=>"material", "value"=>"jean"}], "send_datum"=>{"name"=>"asdfasd", "upc"=>"243252353", "availableOn"=>"07/12/2020", "properties"=>[{"name"=>"material", "value"=>"jean"}]}}
class SendDataController < ApplicationController
protect_from_forgery with: :null_session
def save
product = Product.create(name:params[:name], upc:params[:upc].to_i, available_on:params[:availableon])
x=0
while x < params[:properties].length
property = product.properties.create(name:params[:properties][x][:name])
property.product_properties.create(value:params[:properties][x][:value])
x += 1;
end
end
end
This line is the one I cannot seam to get to work:
property.product_properties.create(value:params[:properties][x][:value])
This is my first react on rails project and understanding table assoc. has been a real challenge but I am getting there.
Models:
class Property < ApplicationRecord
belongs_to :product
has_many :product_properties
end
class Product < ApplicationRecord
has_many :properties
has_many :product_properties
end
class ProductProperty < ApplicationRecord
belongs_to :property
belongs_to :product
end
Migration:
class CreateProducts < ActiveRecord::Migration[5.2]
def change
create_table :products do |t|
t.string :name
t.string :upc
t.datetime :available_on
t.timestamps
end
end
end
class CreateProperties < ActiveRecord::Migration[5.2]
def change
create_table :properties do |t|
t.string :name
t.timestamps
end
end
end
class CreateProductProperties < ActiveRecord::Migration[5.2]
def change
create_table :product_properties do |t|
t.string :value
t.timestamps
end
end
end
class AddProductRefToProperties < ActiveRecord::Migration[5.2]
def change
add_reference :properties, :product, foreign_key: true
end
end
class AddProductRefToProductProperties < ActiveRecord::Migration[5.2]
def change
add_reference :product_properties, :product, foreign_key: true
end
end
class AddPropertiesRefToProductProperties < ActiveRecord::Migration[5.2]
def change
add_reference :product_properties, :property, foreign_key: true
end
end
Schema:
ActiveRecord::Schema.define(version: 2018_09_24_163027) do
create_table "product_properties", force: :cascade do |t|
t.string "value"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "product_id"
t.integer "property_id"
t.index ["product_id"], name: "index_product_properties_on_product_id"
t.index ["property_id"], name: "index_product_properties_on_property_id"
end
create_table "products", force: :cascade do |t|
t.string "name"
t.string "upc"
t.datetime "available_on"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "properties", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "product_id"
t.index ["product_id"], name: "index_properties_on_product_id"
end
end
UPDATE::
It is related to the fact that the product_property is getting the property_id from property but is not getting the product_id from the product. How do I fix that?
Any help is greatly appreciated. Thanks!!
The issue was I had my associations set up incorrectly. As #DavidAldridge pointed out I needed to link Property to Product through product property.
class Product < ApplicationRecord
has_many :product_properties
has_many :properties, through: :product_properties
end
class ProductProperty < ApplicationRecord
belongs_to :property, required: false
belongs_to :product, required: false
end
class Property < ApplicationRecord
has_many :product_properties
has_many :products, through: :product_properties
accepts_nested_attributes_for :product_properties
end

adding t.reference or t.belongs_to for models in has many through

I have a has many through relationship. Should I have foreign key in Physician and patient model?
class CreateAppointments < ActiveRecord::Migration
def change
create_table :physicians do |t|
t.string :name
t.references :patient, index: true
t.timestamps null: false
end
create_table :patients do |t|
t.string :name
t.references :physician, index: true
t.timestamps null: false
end
create_table :appointments do |t|
t.belongs_to :physician, index: true
t.belongs_to :patient, index: true
t.datetime :appointment_date
t.timestamps null: false
end
end
end
You don't need need to add index in both physicians and patients table, since your appointments table holding both of these indexes. You can access Patients of a Physician, vice versa through this association itself, all you need to do is mention it in your physician and patient model,
class Physician < ActiveRecord::Base
has_many :appointments
has_many :patients, through: :appointments
end
class Appointment < ActiveRecord::Base
belongs_to :physician
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :appointments
has_many :physicians, through: :appointments
end
and your migration file should be like this.
class CreateAppointments < ActiveRecord::Migration
def change
create_table :physicians do |t|
t.string :name
t.timestamps null: false
end
create_table :patients do |t|
t.string :name
t.timestamps null: false
end
create_table :appointments do |t|
t.belongs_to :physician, index: true
t.belongs_to :patient, index: true
t.datetime :appointment_date
t.timestamps null: false
end
end
end
When you are adding references that will generate the foreign key in its corresponding table.

Rails4 how to create the model relationship on join table

this is user table:
create_table :users do |t|
t.string :name
t.string :password
t.string :department
t.timestamps
end
this is meet table:
create_table :meets do |t|
t.string :name, null: false
t.string :state, null: false
t.string :description, null: false
t.string :location, null: false
t.float :spend, null: false
t.timestamps
end
The following is a relationship between user and meet:
user can create many meets
a meet can have many participants(users)
I am new to study rails, i tried to create migration and model, But i do not know the correct way:
User can create many meets, I think i can add reference in meets migrate to create a one to one relationship
t.references :users
a meet can have many users, I think i must create a join table:
rails g migration CreateJoinTableUsersMeets user meet
The above command will auto generate a migration file:
create_join_table :Users, :Ploys do |t|
t.index [:user_id, :ploy_id]
t.index [:ploy_id, :user_id]
end
But i want know how to create model relationship on join tabel?
This is how I would do it.
create_table :users do |t|
t.string :name
t.string :password
t.string :department
t.timestamps
end
create_table :meets do |t|
t.string :name, null: false
t.string :state, null: false
t.string :description, null: false
t.string :location, null: false
t.float :spend, null: false
t.references :creator, class_name: "User"
t.timestamps
end
create_table :participations do |t|
t.references :user
t.references :meet
end
add_index :participations, [:user_id, :meet_id]
add_index :participations, [:meet_id, :user_id]
class User < ActiveRecord::Base
has_many :meets, through: :participations
has_many :created_meets, class_name: "Meet", foreign_key: "creator_id"
end
class Meet < ActiveRecord::Base
has_many :users, through: :participations
belongs_to :creator, class_name: "User"
end
You do not create a one to one relationship in the table but you just have to create a join table called participations. That model will have a reference to a user and a meet. Then, you can specify has_and_belongs_to_many by adding the above code to both models. The point is that it uses the join table to create associations. Comment if you have any other question :)

Rails has_one and belongs_to migration?

I'm trying to establish a relationship between two models in Rails but I am having trouble figuring out what I need to do in my migration. Any help is much appreciated.
I want each business to have a type/category such as "Automotive", or "Restaurant and Bar".
Business.rb:
class Business < ActiveRecord::Base
has_one :category, :foreign_key => "cid"
attr_accessible :description, :email, :facebook, :foursquare, :google, :manager,
:mobile, :name, :phone, :url, :yelp
end
Type.rb:
class Type < ActiveRecord::Base
attr_accessible :cid, :category
belongs_to :business
end
CreateTypes migration file:
class CreateTypes < ActiveRecord::Migration
def change
create_table :types do |t|
t.integer :cid
t.string :category
t.references :business
t.timestamps
end
add_index :types, :cid
end
end
CreateBusinesses migration file:
class CreateBusinesses < ActiveRecord::Migration
def change
create_table :businesses do |t|
t.string :name
t.string :url
t.string :phone
t.string :manager
t.string :email
t.boolean :mobile
t.boolean :foursquare
t.boolean :facebook
t.boolean :yelp
t.boolean :google
t.text :description
t.integer :cid
t.timestamps
end
end
end
It would be easiest for you to keep with rails naming conventions. If I got it correctly, a business belongs to a Type/Category. let the business reference the type. add a belongs_to on the business side and a has_many on the type/category side. Roughly like this:
class Business < ActiveRecord::Base
attr_accessible :description, :email, :facebook, :foursquare, :google, :manager, :mobile, :name, :phone, :type_id, :url, :yelp
belongs_to :type
end
class Type < ActiveRecord::Base
has_many :businesses
end
class CreateTypes < ActiveRecord::Migration
def change
create_table :types do |t|
t.string :category
t.timestamps
end
end
end
class CreateBusinesses < ActiveRecord::Migration
def change
create_table :businesses do |t|
t.string :name
t.string :url
t.string :phone
t.string :manager
t.string :email
t.boolean :mobile
t.boolean :foursquare
t.boolean :facebook
t.boolean :yelp
t.boolean :google
t.text :description
t.integer :type_id
t.timestamps
end
end
end
Your businesses table must have integer field cid, because it you set it as a foreign key. You types table must not have cid field. The types.id field will be used to create a relationship. Note that belongs_to method doesn't have foreign_key option, you should remove it from its call.
I can advise you not to change foreign key name without a reason. If you don't specify foreign key, it defaults to type_id.

Resources