Change foreign key column name in rails - ruby-on-rails

I have a Project migration class like this:
class CreateProjects < ActiveRecord::Migration
def change
create_table :projects do |t|
t.string :title
t.text :description
t.boolean :public
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
end
end
It creates a column name user_id in projects table but I want to name the column owner_id so I can use project.owner instead of project.user.

You can do it two ways:
#app/models/project.rb
class Project < ActiveRecord::Base
belongs_to :owner, class_name: "User", foreign_key: :user_id
end
OR
$ rails g migration ChangeForeignKeyForProjects
# db/migrate/change_foreign_key_for_projects.rb
class ChangeForeignKeyForProjects < ActiveRecord::Migration
def change
rename_column :projects, :user_id, :owner_id
end
end
then:
$ rake db:migrate

Related

rails - can't save data in associated models in RoR

I have 2 Models with association has_many along with cascade property between them.
class ServicesBrandDetail < ApplicationRecord
has_many :services_brands, foreign_key: "brand_id", dependent: :delete_all
end
class ServicesBrand < ApplicationRecord
belongs_to :services_brand_details, foreign_key: "brand_id",
end
Migration for both files
class CreateServicesBrandDetails < ActiveRecord::Migration[6.1]
def change
create_table :services_brand_details do |t|
t.string :brand
t.string :mail_list
t.string :cc_list
t.timestamps
end
end
end
class CreateServicesBrands < ActiveRecord::Migration[6.1]
def change
create_table :services_brands do |t|
t.string :warehouse
t.references :brand, null: false, foreign_key: {to_table: :services_brand_details}
t.timestamps
end
end
end
Now I was able to create and save data in from ServicesBrandDetails model. but the Problem is when i create record from ServiceBrand It created record perfectly but i was not able to store data in DB.
record = ServicesBrandDetail.create(:brand => "a", :mail_list => 'abc#mail.com', :cc_list => 'def#mail.com')
record.save
Record successfully stored in DB.
child = record.services_brands.new(:warehouse => "in") <-- record was created successfully.
child.save
it give me error
C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/activerecord-6.1.5/lib/active_record/inheritance.rb:237:in `compute_type': uninitialized constant ServicesBrand::ServicesBrandDetails (NameError)
Please follow proper Naming convention
This article might help - https://www.bigbinary.com/learn-rubyonrails-book/summarizing-rails-naming-conventions
In ServiceBrand Model
class ServiceBrand < ApplicationRecord
belongs_to :brand, class_name: 'ServiceBrandDetail'
end
belongs_to should be foreign key name i.e brand in your case
You can delete existing models and tables from your codebase and try below one. (I've tested)
class ServiceBrandDetail < ApplicationRecord
has_many :service_brands, foreign_key: :brand_id, dependent: :delete_all
end
class ServiceBrand < ApplicationRecord
belongs_to :brand, class_name: 'ServiceBrandDetail'
end
Migration for both files
class CreateServiceBrandDetails < ActiveRecord::Migration[6.1]
def change
create_table :service_brand_details do |t|
t.string :brand
t.string :mail_list
t.string :cc_list
t.timestamps
end
end
end
class CreateServiceBrands < ActiveRecord::Migration[6.1]
def change
create_table :service_brands do |t|
t.string :warehouse
t.references :brand, null: false, foreign_key: {to_table: :service_brand_details}
t.timestamps
end
end
end
Then try to create model objects which you tried in your question. It will work 👍🏽
In your model ServicesBrand you have to use singular association name for belongs_to
Change this belongs_to :services_brand_details to this belongs_to :services_brand_detail
class ServicesBrand < ApplicationRecord
belongs_to :services_brand_detail, foreign_key: "brand_id"
end

ActiveModel::MissingAttributeError: can't write unknown attribute `team_id`

I find this issue when I try to save the a team, how can I solve it? I am trying to deal with these associations for so long, if you guys do other issues, just let me know, please (this association has been a nightmare).
Here are the models
class Field < ApplicationRecord
end
class Game < ApplicationRecord
belongs_to :field
belongs_to :organiser
has_one :team
has_many :players, through: :team
end
class Organiser < ApplicationRecord
has_many :games
end
class Player < ApplicationRecord
has_many :teams
has_many :games, through: :teams
end
class Team < ApplicationRecord
has_many :players
belongs_to :game
end
Here are the migrations
class CreateOrganisers < ActiveRecord::Migration[5.2]
def change
create_table :organisers do |t|
t.string :name
t.string :email
t.integer :age
t.timestamps
end
end
end
class CreatePlayers < ActiveRecord::Migration[5.2]
def change
create_table :players do |t|
t.string :name
t.integer :age
t.string :address
t.timestamps
end
end
end
class CreatePlayers < ActiveRecord::Migration[5.2]
def change
create_table :players do |t|
t.string :name
t.integer :age
t.string :address
t.timestamps
end
end
end
class CreateFields < ActiveRecord::Migration[5.2]
def change
create_table :fields do |t|
t.string :location
t.string :transports
t.timestamps
end
end
end
class CreateGames < ActiveRecord::Migration[5.2]
def change
create_table :games do |t|
t.references :field, foreign_key: true
t.references :organiser, foreign_key: true
t.integer :size
t.timestamps
end
end
end
class CreateTeams < ActiveRecord::Migration[5.2]
def change
create_table :teams do |t|
t.references :player, foreign_key: true
t.references :game, foreign_key: true
t.timestamps
end
end
end
class AddTeamToGames < ActiveRecord::Migration[5.2]
def change
add_column :games, :team, :reference
end
end
The idea is to make sure that each game will have a team of certain people. I want to access the people through game.team.player
Your migrations doesn't have any kind of references to connect these tables.
For example Game has_one :team is not going to create this references for you, to call game.team needs a column called game_id in teams table.
To add the reference you can create a migration for it:
rails g migration AddGameToTeams game:references
This will create that migration file may look like this:
class AddGameToTeams < ActiveRecord::Migration
def change
add_reference :teams, :game, index: true
end
end
Depending in the version you running rails this migration file may differ a little with adding an extra line regarding foreign_key.
Run the generated migration with rails db:migrate and it should work.
You need to apply the same concept to the rest of your tables.
Hope this helps.

Rails: Multiple references to the same model error

I have a Message model that has a user and a teammember (both are users).
The models are:
# message.rb
class Message < ActiveRecord::Base
belongs_to :user
belongs_to :teammember, :class_name => "User", :foreign_key => 'teammember_id'
end
# user.rb
class User < ActiveRecord::Base
has_many :messages
end
And I have this migration:
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.references :user, index: true, foreign_key: true
t.references :teammember, index: true, foreign_key: true
t.text :body
t.boolean :read, default: false
t.timestamps null: false
end
end
end
When I run the rake db:migrate locally (with sqlite3) everything works fine.
The problem is that when I deploy to heroku (that uses postgresql) and run
heroku run rake db:migrate
It raises the next error:
PG::UndefinedTable: ERROR: relation "teammembers" does not exist
: ALTER TABLE "messages" ADD CONSTRAINT "fk_rails_7efc67ccc9"
FOREIGN KEY ("teammember_id")
REFERENCES "teammembers" ("id")
Do you know what is the problem and how can I fix it?
Rails guesses based on the association, because you're referencing a table it can't determine from the association you'll have to add it yourself.
class CreateMessages < ActiveRecord::Migration
def change
create_table :messages do |t|
t.references :user, index: true, foreign_key: true
t.references :teammember, index: true
t.text :body
t.boolean :read, default: false
t.timestamps null: false
end
add_foreign_key :messages, :users, column: :teammember_id
end
end

Ruby on rails does not create foreign keys on database

Is it normal that rails doesn't create the foreign keys on database? Or I'm doing something wrong?
I have these models:
class City < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :city
end
and their respective migrations:
class CreateCities < ActiveRecord::Migration
def change
create_table :cities do |t|
t.string :name
t.timestamps
end
end
end
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.references :city, index: true
t.timestamps
end
end
end
That's correct. Rails doesn't automatically add foreign keys, you have to specify it yourself in the migration like you have.
t.references :city is effectively the same as t.integer :city_id.
Are you saying that even though are specifying a foreign key, that you aren't seeing the results?

Ruby on Rails: Postgres Relation 'lists' does not exist

I'm getting a weird error. I had sqlite3 working and now switching over to postgres, i'm getting this error.
I have migrations, and I had to add a new column.
create_ideas migration
class CreateIdeas < ActiveRecord::Migration
def change
create_table :ideas do |t|
t.string :name
t.text :description
t.string :picture
t.timestamps
end
add_foreign_key :ideas, :lists
end
end
add_list_id_column_to_ideas migration
class AddListIdColumnToIdeas < ActiveRecord::Migration
def change
add_column :ideas, :list_id, :integer
end
end
What is wrong with my foreign key? I get the error when I do rake db:migrate
I have another migration with foreign key, and no errors yet? Maybe its catching the first error first before seeing the other one, but I have this one too:
create_comments migration
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.string :user_name
t.text :body
t.integer :idea_id
t.timestamps
end
add_foreign_key :comments, :ideas
end
end
last migration I have create_lists
class CreateLists < ActiveRecord::Migration
def change
create_table :lists do |t|
t.string :name
t.text :description
t.string :picture
t.timestamps
end
end
end
Any clue why I'm getting errors?
Thanks
edit
my relationships
comments model
belongs_to :idea
idea model
belongs_to :list
has_many :comments
list model
has_many :ideas

Resources