I have two models: users and emails.
I have separated this tables because we want the user to be able to have many emails in the same user account, and also easily check uniqueness of email values among accounts.
primary_email_id is a FK of a unique email, but also a user has many emails. How do I say that in the rails model?
I was trying
class User < ActiveRecord::Base
# relations
has_many :emails
has_one :primary_email
end
…
class Email < ActiveRecord::Base
# relations
belongs_to :user
end
Is that correct? How does rails know when I say primary_email I'm making reference to the emails table?
By the way, both migrations are:
create_table :users do |t|
t.string :username
t.string :first_name
t.string :last_name
t.binary :password
# t.integer :primary_email
t.timestamps null: false
end
create_table :emails do |t|
# t.integer :user
t.string :email
t.boolean :verified
t.timestamps null: false
end
add_reference :users, :primary_email, references: :emails, index: true, foreign_key: true
add_reference :emails, :user, index: true, foreign_key: true
Related
I have 2 models (Service and Town) with a :has_many :through relationship. I want to be able to find every services of a town and every towns of a service.
Also in front I should never be able to see my Town ID so I can link service and town only with the zip_code of a town.
Here is all my migrations
create_table :services, type: :uuid do |t|
t.string :name, null: false
t.string :action, null: false
t.string :kind, null: false
end
create_table :towns do |t|
t.string :name, null: false
t.stirng :zip_code, null: false
t.string :country, null: false
end
create_table :services_towns do |t|
t.belongs_to :service
t.belongs_to :town
t.string :zip_code, null: false
t.index :zip_code
end
here are my models
class Town < ApplicatonRecord
has_many :services_towns, primary_key: :zip_code, foreign_key: :zip_code
has_many :services, through: :services_communes
end
class Service < ApplicationRecord
has_many :services_towns
has_many :towns, through: :services_communes
end
class ServicesTown < ApplicationRecord
belongs_to :service
belongs_to :town, primary_key: :zip_code, foreign_key: :zip_code
end
#service.towns and #town.services are working well in my rails console but if I try a more complex search like
Service.where(towns: [towns_array]) I got the following error
PG::UndefinedColumn: ERROR: column services.zip_code does not exist
With this request I would like to have every Services from every Towns I have passed in the array.
I guess the problem are because of my primary_key or foreign_key but I don't know what to do better
You need to fix your query, try this
Service.joins(:towns).where(towns: { zip_code: towns_array })
or
Service.joins(:towns).where("towns.zip_code IN (?)", towns_array)
Hope that helps!
I'm kind of new in Rails and couldn't make my Models relationship to work, and I don't know the reason. I've tried in many ways and followed many different tutorials, but couldn't figure out the right way. Do you know what's wrong with my code? How can I test it?
I have two models, with has_one association User and Profile. Profile belongs to User. So every time I add a user, I would also add a Profile.
This is the migration file for User model
class CreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users do |t|
t.string :email
t.string :password_digest
t.timestamps
end
end
end
This is migration file for Profile model
class CreateProfiles < ActiveRecord::Migration[5.1]
def change
drop_table :profiles
create_table :profiles do |t|
t.string :name
t.string :lastname
t.string :phone
t.string :address
t.string :city
t.string :state
t.string :country
t.string :gender, :limit => 10
t.string :zipcode
t.references :users, foreign_key: true
t.timestamps
end
end
end
model Profile
class Profile < ApplicationRecord
belongs_to :user
end
model User
class User < ApplicationRecord
has_secure_password
has_one :profile
end
Thank you very much!
I think the problem might be with the migration.
Profile belongs to User, so in the create_profiles migration you should have:
t.references :user, foreign_key: true
(user instead of users).
With your code, the Profile model will have users_id field when it should have user_id.
I'm a Rails beginner trying to build my first web app.
In my web app Physiotherapists can add Patients and create ExercisePlans from a list of Exercises. I sketched out the model relationships as follows underneath. Is this the correct way to do it?
I am mostly concerned about the following:
Is a join table the correct way to match exercises to exercise_plans?
Do I need a join table to match physiotherapists to exercise_plans?
RELATIONSHIPS
Physiotherapist
has_many :patients
has_many :exercise_plans
Patient
has_many :exercise_plans
belongs_to :physiotherapist
Exercise
has_many :exercise_plans
ExercisePlan
belongs_to :patient
belongs_to :physiotherapist
has_and_belongs_to_many :exercises
MIGRATIONS
class CreatePhysiotherapists < ActiveRecord::Migration
def change
create_table :physiotherapists do |t|
t.string :first_name
t.string :last_name
t.string :company_name
t.string :email
t.string :password
t.timestamps
end
class CreatePatients < ActiveRecord::Migration
def change
create_table :patients do |t|
t.string :first_name
t.string :last_name
t.string :email
t.integer :physiotherapist_id #the physiotherapist to which the patient belongs
t.timestamps
end
class CreateExercises < ActiveRecord::Migration
def change
create_table :exercises do |t|
t.string :title
t.string :category
t.string :bodypart
t.text :instructions
t.timestamps
end
class CreateExercisePlans < ActiveRecord::Migration
def change
create_table :exercise_plans do |t|
t.string :name
t.integer :exercise_id #an array of exercises that are in the plan
t.integer :physiotherapist_id #the physiotherapist who created the plan
t.integer :patient_id #the user for whom the exercise plan is made
t.timestamps
end
#join table for the has_and_belongs_to_many relationship with exercises
create_table :exercise_plans_exercises do |t|
t.integer :exercise_id
t.integer :exercise_plan_id
end
end
1) Yes. However, I'd use has_many :through instead of has_and_belongs_to_many. It is a much more flexible approach and allows for a customization of exercise for each specific exercise plan. For example, you might want to store a number of repetitions or duration in Activity model. http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
ExercisePlan
has_many :activities
has_many :exercises, through: :activities
Exercise
has_many :activities
has_many :exercise_plans, through: :activities
Activity
belongs_to :exercise
belongs_to :exercise_plan
2) No, there's no need for an additional join table.
Notes:
You don't really need to have physiotherapist_id in exercise_plans, because you already have it in patients. You can exercise_plan.patient.physiotherapist.
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 :)
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.