ActiveRecord fundamentally incompatible with composite keys? - activerecord

I have been attempting to use subsonic for a project on which I'm working. All was going quite well until I encountered a link table with a composite primary key. That is a key made up of the primary keys of the two tables it joins. Subsonic failed to recognize both keys which was problematic. I was going to adjust subsonic to support compound keys but I stopped and though "Maybe there is a reason for this". Normally active record relies on a single primary key field for every record, even in link tables. But is this necessary? Should I just give up on active record for this project or continue with my modifications?

Ruby on Rails does not support composite primary keys in model object out of the box. However, there are plugins that accomplish that, for example this.
You can have composite primary key on a join table, but Rails will not create that primary key, you have to create it manually.
See this guide.

Related

is bad habit to don't use foreign in migration laravel?

I am new in laravel. In my tutorial video teacher use foreign in migration but,i can create my relationships without it and use just belongTo and hasMany.When i use foreign can not delete one post easily (error is you can not delete because parent foreign has child ......).
my question is my way is good or not? and why?
Thank you all
Your way is good but I think foreign keys are better. Had you not had that foreign key, you would have deleted the post but all that post's children (referred to as orphans because they no longer have a parent) would have stuck around. In order to get around the foreign key error, you would need to first delete all the children for that post, and then delete the post.
The good news is foreign keys can also do this for you so you don't need to worry about keeping track of all the children. When you setup the foreign key, if you add the on delete cascade clause, when deleting the post, the database would automatically remove all of the posts's children for you and deleting a post without first deleting the children would no longer result in an error.
If it's your preference to keep the children around even when the post is deleted, you can use on delete set null instead which would simply set the children's foreign key to null rather than delete the record.
This is all useful for enforcing data integrity (databases should contain only accurate and valid data).
The answer really is not 'is this good practice in Laravel' so much as 'is this good practice for database management'.
There are many articles on the topic as to the good and bad side of using foreign keys. Here is a good explanation on the DBA stack exchange
https://dba.stackexchange.com/questions/168590/not-using-foreign-key-constraints-in-real-practice-is-it-ok
My personal preference is to use them to maintain data integrity. The real power comes in adding cascading deletes to the relationship (if applicable to your design).
It really comes down to how good you want your database to be.The main reasons to use foreign keys in your database are
To prevent actions that would destroy links between your tables
This would prevent the invalid data from being inserted to the foreign key column as it has to point to a existing value
Also defining foreign keys makes your query faster depending on database I don't know the exact milliseconds but if I find it out I will post it.
Well from the laravel point of view the way you do is a better way as this is how one of the main teacher of the Laravel(Jeffrey Way) teaches in the getting started with laravel series.
Foreign Keys are the way to define relationship between tables in your database whereas Laravel belongsTo() or hasMany() is a way to define relationship between tables in Laravel

Changing Primary Key in Oracle

I'm updating a table that was originally poorly designed. The table currently has a primary key that is the name of the vendor. This serves as a foreign key to many other tables. This has led to issues with the Vendor name initially being entered incorrectly or with typos that need to be fixed. Since it's the foreign key to relationships, this is more complicated than it's worth.
Current Schema:
Vendor_name(pk) Vendor_contact comments
Desired Schema:
id(pk) Vendor_name Vendor_contact comments
I want to update the primary key to be an auto-generated numeric key. The vendor name field needs to persist but no longer be the key. I'll also need to update the value of the foreign key on other tables and on join tables.
Is the best way to do this to create a new numeric id column on my Vendor table, crosswalk the id to vendor names and add a new foreign key with the new id as the foreign key, drop the foreign key of vendor name on those tables (per this post), and then somehow mark the id as the primary key and unmark the vendor name?
Or is there a more streamlined way of doing this that isn't so broken out?
It's important to note that only 5 users can access this table so I can easily shut them out for a period of time while these updates are made - that's not an issue.
I'm working with SQLDeveloper and Python/Django.
The biggest problem you have is all the application code which references VENDOR_NAME in the dependent tables. Not just using it to join to the parent table, but also relying on it to display the name without joining to VENDOR.
So, although having a natural key as a foreign key is a PITN, changing this situation is likely to generate a whole lot of work, with a marginal overall benefit. Be sure to get buy-in from all the stakeholders before starting out.
The way I would approach it is this:
Do a really thorough impact analysis
Ensure you have complete regression tests for all the functions which rely on the Vendor data
Create VENDOR_ID as a unique key on VENDOR
Add VENDOR_ID to all the dependent tables
Create a second foreign on all the dependent tables referencing VENDOR_ID
Ensure that the VENDOR_ID is populated whenever the VENDOR_NAME is.
That last point can be tackled by either fix the insert and update statements on the dependent tables, or with triggers. Which approach you take will determine on your application design and also the number of tables involved. Obviously you want to avoid the performance hit of all those triggers if you can.
At this point you have an infrastructure which will support the new primary key but which still uses the old one. Why would you want to do this? Because you could go into Production like this without changing the application code. It gives you the option to move the application code to use VENDOR_ID across a broader time frame. Obviously, if developers have been keen on coding SELECT * FROM you will have issues that need addressing immediately.
Once you've fixed all the code you can drop VENDOR_NAME from all the dependent tables, and switch VENDOR_NAME to unique key and VENDOR_ID to primary key on the master table.
If you're on 11g you should check out Edition-Based Redefinition. It's designed to make this sort of exercise an awful lot easier. Find out more.
I would do it this way:
create your new sequence
create table temp as select your_sequence.nextval,vendor_name, vendor_contact, comments from vendor.
rename the original table to something like vendor_old
add the primary key and other constraints to the new table
rename the new table to the old name
Testing is essential and you must ensure no one is working on the database except you when this is done.

How can I have a table without primary key in Magento?

In Magento, it is necessary that you create a primary key in order your grid and module to work. But, I don't have primary key in my table and don't want to create it. Is it possible to make my module work properly without primary key?
Magento is giving error Column not found: 1054 Unknown column 'main_table.modulename_id' in 'field list' as it doesn't find primary key id in the table while displaying grid.
Without auto-increment it can be done with:
$this->_isPkAutoIncrement = false; in the model. Is there anything like that for primary key as well?
I searched on net without any luck. Any help will be highly appreciated.
If you will not use model/collection for this table, you can do this. If not -- you cann't (without rewrites). See newsletter queue and queue_link tables -- there are no model for queue_link table (it has primary key, but you can use your table without it if you will wok in such way), all things are done in queue resource.
The Magento ORM is setup in a way which will require you specify a primary field. You should always have primary key anyway, I can't imagine a situation where you would want one as it would no longer be suited to a database...
I would imagine you may want a natural/composite key rather than a surrogate key, but I am not sure if that's what you meant?

How to use ActiveRecord (without Rails) with database that doesn't have primary keys

I now writing automation program for system based on MSSQL Server, using Ruby 1.9.3 and ActiveRecord 3.1.6 without Rails.
Tables have nonstandard ids (stk_id, urb_id, instead of id), also some tables haven't primary keys.
Before I added column id and set it as primary key my program worked very slowly. I waited nearly 3 minutes while the program makes two operations of selection and some little processing in table with 9000 records. But when I added column id and set it as primary key, these operations were finished in less then 10 secs.
Yet another problem I found in deletion operation: it doesn't work at all without primary key in table. Error when trying to delete without primary key:
undefined method `to_sym' for nil:NilClass
I can't modify the table structure of the production database. Maybe someone knows how to solve this problem without adding id columns and setting primary keys?
Remark: A database without primary keys is BAD !
http://www.helium.com/items/1539899-why-a-relational-database-needs-a-primary-key
Using nonstandard keys is no problem, just use self.primary_key = "stk_id"
You may also use composite_primary_keys:
https://github.com/drnic/composite_primary_keys
Create indexed views on each of the tables with no primary key. A unique clustered index as well as other indexes as needed can be applied. Including a single table in the view should prevent you from violating the many conditions an indexed view requires/prohibits.
I suggest looking into using Sequel instead of ActiveRecord. It is not opinionated about the database schema like ActiveRecord is and may be easier to use with a database schema you can't modify.

How do i make ActiveRecord work on Tables with multiple columns as Primary keys?

How do i use ActiveRecord on existing DB with multiple columns as primary key and no ID column? I had to write extensions/hacks on set_primary_key, update and delete methods. But im not sure if it'll work on future versions. Is there a way to make ActiveRecord work in such cases without hacks?
ActiveRecord doesn't support composite primary keys. Here is a library that purports to add support though.

Resources