Rails create join table how to validate uniqueness of pair - ruby-on-rails

I've created a join table with
rails generate migration CreateJoinTableFoosBars foos bars
and it has indeed created a working joining table, however I can't see the model for it and thus I can't add the
validates_uniqueness_of :foo_id, scope: :bar_id
How can I do it in this case? Thanks in advance.

Add a unique index that includes both columns. That will prevent you from inserting a record that contains a duplicate foo_id/bar_id pair.
add_index :foo_bars, [:foo_id, :bar_id], unique: true

generating a migration does not generate a model as well. If you use the model generator then it will also produce a migration file and the model file:
rails generate model foo_bar foo_id:integer bar_id:integer

Related

Adding 2 references to a rails model from same model

I have a model called WalksSection and another called WalkSectionButton. I have created the WalksSection model (and done migration).
Now I want to create WalkSectionButton but want to create two references between the two tables:
walk_sections.id = walk_section_buttons.section_button_id
walk_sections.id = walk_section_buttons.next_section_button_id
The first is the standard one but the other (I think) I need to tell the migration and the model the column name.
So the standard one in the model is
belongs_to :WalkSection
and in the migration is
t.references :WalkSection, foreign_key: true
So I guess I need to have a second line in model and migration which specifies the foreign (and primary) key name but not sure of the syntax.
The other way to do this maybe is to run the migration to create the first reference then do another migration that adds the column and key for the second foregn key.
add_column :walk_section_buttons, :next_section_button_id, :integer
add_foreign_key :walk_section_buttons, :walk_sections, column: :next_section_button_id, primary_key: :id
But not sure what to do to the model. Maybe I don't need to but in the WalksSections model I think I should add a has_many, but again would need to specify a column name for the second one.

migrating from two ids to a polymorphic association

I have a table that currently belongs to 2 different models. What I'd like to do is turn these into a polymorphic association instead.
Currently the table line_items have a cart_id and an order_id now what I'd like to do is migrate both of these ids into a polymorphic one called itemable_id and fix the itemable_type to the correct one.
How would I go about creating a migration for this, or what's the go-to solution for this case, where you have two ids columns and want to make it polymorphic?
Try following and add belongs_to :itemable, polymorphic: true in LineItem model
rails generate migration RemoveCartRefFromLineItems cart:references
rails generate migration RemoveOrderRefFromLineItems order:references
rails g migration AddItemableIdToLineItems itemable_id:integer
rails g migration AddItemableTypeToLineItems itemable_type:string

Efficiently create a join table migration

rails g migration CreateJoinTable zombie:index role:index
This creates this migration:
class CreateJoinTable < ActiveRecord::Migration
def change
create_join_table :zombies, :roles do |t|
t.index [:zombie_id, :role_id]
t.index [:role_id, :zombie_id] # I'd be happy if it didn't have this!
end
end
end
That migration is nearly there, but why do I have four indexes rather than two? Where in my generate command does it specify to create an extra two sets of indexes for indexes that already exist?
Try this instead:
rails g migration CreateJoinTableRolesZombies roles zombies
The migration comments out the indexes, presumably to show that the create_join_table handles this for you.
Note that in rails 4 the table names must be in sort order. Also, the migration name has been expanded in this example just to make it clear. CreateJoinTable appears in it, which is sufficient.
You've only two indexes, though it might index more than it should. See Index on multiple columns in RoR to explain the array syntax and how that changes t.index.

Does Rails 3.2+ require a join table *in addition to* declaring the has_and_belongs_to_many relation?

I have a number of many-to-many relationships in my app.
I do not need to store information about the relationships themselves, so am using the has_and_belongs_to_many relation in my models.
I've read the Active Record documentation and it seems to confirm my strategy, BUT I'm not clear if I still need to create join tables in the database or if ActiveRecord in Rails 3.2 is smart enough to handle it using the model relations alone.
Any references or explanations would be appreciated.
----- Break -----
If I did need to store data about the relationship itself and I were using has_many => through in my model, would I need to remove the Primary Key from the "through" table (e.g. so that it only has the two foreign keys?)
Thank you!
Yes, you need to create the join table for a has_and_belongs_to_many association. Remember in Rails you need to 'migrate to create'. Using this article as an example, say we have an Account model and a Role model, we can create a join table through this migration:
rails generate migration create_accounts_roles_join_table
Now we will edit the migration file that was just created
create_table :accounts_roles, :id => false do |t|
t.integer :account_id
t.integer :role_id
end
It is important to include :id => false as this will leave off the primary key that is normally generated when you create a table. Also, we specified the two foreign keys account_id and role_id.
run rake db:migrate and add the HABTM associations in both models and everything is set up.
Also, as a side note, adding join_table to the end of the migration generator is not required but is more descriptive and integer can be replaced with references when adding the foreign keys. They are equivalent but maybe a bit more descriptive.
On the second part of your question, you don't need to remove the primary key from the table.

Ruby on Rails database: how to mention foreign key relation by changing app/model/table.rb file how to know they implemented

I am new to RoR. I used "rails generate model ServiceConfigs" command to generate a table.
so may commands are as below
rails generate model ServiceConfigs configs:string
rake db:migrate
-- can see app/db/service_config.rb created.
Now edited service_config.rb file to add 2 columns and which has a foreign key relation to service table. So here is code
class ServiceConfigs < ActiveRecord::Base
belongs_to :service, :dependent => :destroy
validates_presence_of :configs
end
Now when I login to underline database, and look at the table I don't see foreign key relation in table schema. Whats wrong/more I need to do?
highly appreciate your time and help
Krishna
So a few notes for you as you're getting started here: Firstly, I'd name your model in the singular form, as though you are describing a single instance of it: ServiceConfig and in the case where it belongs to a service, you may want to think of a different name all together.
Secondly validates_presence_of suggests that you have that field, so firstly, I'd remove the validation until you know that your DB has that column and that the migration worked. You can make sure by looking at your migration file and confirming that the column is being created.
You can define the relationship the "rails way" in your migration too:
http://guides.rubyonrails.org/association_basics.html
create_table :service_configs do |t|
t.string :configs
t.references :service
t.timestamps
end
Update
If you want to rerun a particular migration run:
rake db:migrate:redo VERSION=20100421175455
You can take a look in your schema to see what migration you are currently at as well. And you can also take a look at the schema to see what your DB is expected to look like as well.

Resources