So I've got two models, State and Acquisition. State has_many Acquisitions. I felt like an autoincrementing integer primary key for 51 records was rather silly. So I altered the model for the State to be the PK (State being the two letter abbreviation; I'm not storing the actual state name anywhere:
class State < ActiveRecord::Base
self.primary_key = "state"
has_many :acquisition_histories
end
The problem is when I created my Acquisition model, it created the foreign key column state_id as an integer. More specifically, the script/generated migration did:
class CreateAcquisitions < ActiveRecord::Migration
def self.up
create_table :acquisitions do |t|
t.date :date
t.string :category
t.text :notes
t.references :state
t.timestamps
end
end
I'm assuming that t.references data type sets it to int. The problem is my create method on my Acquisition class is trying to put a state abbreviation into the state_id field on the table acquisitions (and yes, it's called state_id on the database, even though it says :state in the migration script). The method doesn't fail, but it does put a 0 in the state_id field and the records go into the ether.
-
Rails works best when you don't fight against the defaults. What harm does it do to have an integer primary key on your state table?
Unless you're stuck with a legacy schema that you have no control over, I'd advise you to stick to the Rails defaults—convention over configuration, right?—and concentrate on the important parts of your app, such as the UI and the business logic.
Mike Woodhouse : Well, there's a (probably memory-cached and tiny) database overhead when you have to keep including the state table to get the code. But it's probably over-optimisation. I do that, but I'm old and it used to matter more in VAX 8700 days.John Topley : For that sort of thing I tend to define a constant in the State class i.e. ALL = State.all and then use State::ALL as the source for dropdowns etc. That way, the SQL query only runs at start-up in Production.fr0man : I'm not worried about performance at all, I just don't like the concept of an extra unique identifier. But I'm going to go back with the convention, assuming I can figure out how to back everything back out. I'm fairly new to Rails. -
You want to follow the Rails conventions. The extra primary key is not an issue in any way. Just use it.
-
I had a bit of experience with string used as primary keys and it's a pain in the ***. Remember that by default if you want to pass an object with the default :controller/:action/:id pattern, the :id will be a string and this will probably lead to routing problems if some ids get weirdly formatted ;)
-
I'm working on a project that uses UUIDs as primary keys, and honestly, I don't recommend it unless you're certain you absolutely need it. There are a ton of Rails plugins out there that will not work unmodified with a database that uses strings as primary keys.
-
I really need a long as a primary key, because my real primary key...is bigger than a breadbox. Is there really no sensible way to work around atleast having a non-default type?
-
Proper relational database theory in Rails? oh no no... that's bad. You will burn in the fiery pits of RoR hell!
0 comments:
Post a Comment