Search code examples
ruby-on-railsforeign-keysdependenciesmodel-associations

Rails: associations for models, using :dependent and :foreign keys


I'm making my first Rails app (actually it's my first programming experience) and I have a few questions about models and associations.

My first app is blog.
Blog have users. Users have posts.
One post have one category.
Post also can have tags.
One tag have one category (just like the post).
For example:
Category "Work" have tags "sql", "analytics", "excel" etc.
Category "Personal" have tags "travel", "photo", "surfing" etc.

http://img18.imageshack.us/img18/2213/3m1.png
Here's the sketch of database structure with associations.

And here's the list of my questions:

  1. How can I optimize this structure of models? Or it's ok? (I have a strange feeling about Category model)

  2. Is these associations for models written correct?

  3. Do I need to use :foreign_key and :dependent with associations?

  4. What's gonna happen with associated posts when I'll destroy Category (if :dependent not declared)?

  5. Do I need to have foreign keys on database side?

Thanks for the answers!


Solution

  • (1). How can I optimize this structure of models? Or it's ok? (I have a strange feeling about Category model)

    It all looks good to me

    (2). Is these associations for models written correct?

    They appear to be

    (3). Do I need to use :foreign_key and :dependent with associations?

    foreign_key: No you don't need to, but that is because you are following all the rails conventions

    here is an example where you could use foreign_key attribute, instead of post.user you wanted to call it post.author

    class Post
      belongs_to :author, class_name: "User", foreign_key: "user_id"
    

    OR - if the post had both an author and a reviewer

    class Post
      belongs_to :author, class_name: "User", foreign_key: "user_id"
      belongs_to :reviewer, class_name: "User" # foreign key not needed if users.reviewer_id is the data base column name
    

    dependent: optional, in some cases a good idea

    (4). What's gonna happen with associated posts when I'll destroy Category (if :dependent not declared)?

    has_many :posts, :dependent => :destroy would delete all posts for that category when the category gets deleted

    if you just keep has_many :posts i believe destroying the category will do one of

    • nothing, leaving your posts referencing a category that does not exists (this is bad)
    • update the category_id on the post to NULL (i think in your case you don't want a Post with a null category?)

    I am not a big fan of deleting data - might I suggest putting an is_active attribute on your category? Then you can selectively show category or post data based on that value

    (5). Do I need to have foreign keys on database side?

    No - for a long time rails community has been anti foreign key constraint (not sure if this is still the case) they believe the data integrity should be enforced in the code

    Personally - I am a big fan of database foreign key constraints, you might find you have to fight rails in some cases when using them There are some gems out there that might help generate them for you - https://www.google.com/search?q=rails+gem+foreign+keys

    Notes

    Another good resource: http://guides.rubyonrails.org/association_basics.html (for data model) - rest of guides are very good as well

    Looks like you are headed in the right direction with your data modeling - I might suggest as you start to build your app, start with the simplest thing possible - just a User and a Post, then layer in the other models as you go

    Also for your User - i recommend as you start your app - use the devise gem and its generators to create your User model (NOTE: it will also handle all user creation and authentication needs - views and controllers, a good way to get a jump start on any app)

    rails generate devise:install and then rails generate devise User

    https://github.com/plataformatec/devise