Hybrid composite key in rails - using jsonb field and db column - ruby-on-rails

I need to add a composite primary key to my project but the issue i'm facing is that one of the fields i want to use is in a jsonb field, and the other key is a regular foreign key.
Is it somehow possible for me to set up a hybrid composite key index?
Something like this:
add_index :users, [:phone_number, :department_id], unique: true
Where phone_number is stored in a jsonb field
meta_data: {phone_number: "987654321"}

Related

How to update a table which doesn't have primary id column in rails

I am dealing with legacy code and do not have access to the database. There is a table which does not have a primary id column.
I can find a record using record = Model.find_or_initialize_by(listing_id: rating.pid, criteria_id: 33).
I can increment an attribute with record.rating_count += 1 but when I try to save it with record.save!, it gives the error TypeError: nil is not a symbol nor a string.
I think this is because record does not have a primary id (key) but I am not sure why it doesn't update the record.
If you have any suggestions, please let me know.
I also received the error TypeError: nil is not a symbol nor a string when trying to update a model which has no id column (or other primary key I could use). I had to add one.
You can add a primary key retrospectively using a migration:
add_column :people, :id, :primary_key

on heroku with rails / postgres, uid strings are converted to integers

See this answer for how I implemented string primary keys in my rails app: https://stackoverflow.com/a/1434819/4585520
In the migrations, id: false is specified and some custom postgres execution code is added (i.e. execute "ALTER TABLE users ADD PRIMARY KEY (uid);" where uid is a string). Also, in the models, self.primary_key = :uid is usedThe result is that I have no 'id' columns, just 'uid' columns which are all strings.
However, when I deploy this to Heroku and run my seed generation, I get errors because of duplicate uids. I notice that the added uid values are integers. Perhaps the string values I'm providing are being converted to integers (I have UIDs in a JSON file and am importing those, so no uid generation is occurring), which would explain why they're producing duplicate values.
Why are my uids integers on heroku when they're correctly running as strings in development?
I don't believe this is a Heroku issue, but rather an issue with how the migration tweaked the database.
I've got a Rails app that uses UUID's for primary keys as well. Here's a look at my DB on Heroku Postgres:
Column | Type | Modifiers
------------+-----------------------------+-------------------------------------------
id | uuid | not null default uuid_generate_v4()
data | json | not null
Here was my migration:
enable_extension 'uuid-ossp'
create_table :notifications, id: :uuid do |t|
t.json :data, null: false
end
I'm guessing that the column type may not have been set correctly in your migration. Take a look at your DB on heroku (heroku pg:psql) -- is the uid column an integer that's using a sequence? Do you see something like nextval('users_uid_seq'::regclass)? If so, this requires the column to be an integer. I'd try the following migration to modify your database:
enable_extension 'uuid-ossp'
remove_column :users, :uid
add_column :users, :uuid, :uuid, default: 'uuid_generate_v4()'
This will:
ensure that UUID generation for PG is enabled
remove the current uid column (just to get proper naming)
create a new uuid column, with the type set as uuid and the generation handled on the PG side.
If you're already using Rails to generate UUID's (not recommended, though), you could just go into your database and change the column type from integer to string.
I hope that helps!

Defining table compound primary keys in rails for Cassandra

Given the following pseudo-cql table structure:
CREATE TABLE searches (
category text,
timestamp timestamp,
no_of_searches int,
avg_searches double,
PRIMARY KEY((category, timestamp), no_of_searches)
);
and the following Rails Cequel model:
class Search
include Cequel::Record
# Table columns
key :category, :text
key :timestamp, :timestamp
key :no_of_searches, :int
column :avg_searches, :double
end
when I try to synchronise the model using:
rake cequel:migrate
the following rake error is thrown:
rake aborted!
Cequel::InvalidSchemaMigration: Existing partition keys category,timestamp differ from specified partition keys timestamp
I'm trying to get the above rails model to synchronise with the above table using the partition keys, although it's stating that the two sets of keys are different. I've tried defining the keys in the same order, but has not worked.
My objective is to get the pre-defined database table with partition keys working with the rails model. Any help would be grateful!
The key method supports an options hash as a third parameter. The options hash adds further support to the defined key such as order and partitioning.
Based upon the given table definition it would mean your table columns would look something like this:
# Table columns
key :category, :text, { partition: true }
key :timestamp, :timestamp, { partition: true }
key :no_of_searches, :int
column :avg_searches, :double
Unfortunately this is not documented within the Cequel README, however it is documented within the code, for which can be found here.

How to change primary key in rails migration file?

I need to migrate an old mysql table like this:
Products
name (string, primary_key)
to this schema:
Products
id (integer, primary_key, auto_generated)
name (unique)
I need the Products.id values populated in the new table.
How can i write the rails migration file? I am using Rails 3.2.7
I have 2 problems now:
1. I can't find a method to remove primary key in ActiveRecord::Migration
2. I don't know how to generate values for newly added primary key.
You could execute arbitrary SQL in your migration:
execute "ALTER TABLE `products` DROP PRIMARY KEY"
and then add the new column:
add_column :products, :id, :primary_key
See:
Remove Primary Key in MySQL
how to add a primary key to a table in rails
http://thinkwhere.wordpress.com/2009/05/09/adding-a-primary-key-id-to-table-in-rails/
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
If you're on Postgresql, the syntax is slightly different.
ALTER TABLE <table_name> DROP CONSTRAINT <table_name>_pkey;

Custom non auto-incrementing ActiveRecord "id" column possible?

I'd like to be able to use a custom id (instead of the auto-incrementing default ones) for a Rails model. Basically, all the ids will be iTunes store ids, which are just long integers. Is it possible to turn off the default auto-incrementing ids and require that one be set? These ids will also be used as foreign keys in other models.
Something like this:
create_table :blah, {:id => false} do |t|
t.int :my_custom_int_id
end
execute "ALTER TABLE blah ADD PRIMARY KEY (my_custom_int_id);"
You can manually set the id before you save the model.
a = Model.new
a.id = 8888 #from itunes
a.save
However, you should consider a separate field called itunes_id instead of this approach.

Resources