Boris
Boris

Reputation: 557

Migration has_one and has_many

class Post < ActiveRecord::Base
  has_one :owner, class_name: "User", foreign_key: "owner_id" #creator post
  has_many :users #followers post
end

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

 has_many :posts 
 end

What command line I need to perform to migrate to perform these different relationships between the User and Post tables? Thanks

Upvotes: 0

Views: 883

Answers (1)

PJSCopeland
PJSCopeland

Reputation: 3006

Post should belong_to:owner, because the posts table has the foreign key. Also, its #users is a bit too ambiguously named, as is User#posts.

Here are your models:

class Post < ActiveRecord::Base
  belongs_to :owner, class_name: 'User', inverse_of: :owned_posts # foreign_key: :owner_id will be inferred
  has_many :subscriptions
  has_many :followers, through: :subscriptions, source: :user, class_name: 'User', inverse_of: :followed_posts
end

class Subscription < ActiveRecord::Base
  belongs_to :post
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :owned_posts, class_name: 'Post', inverse_of: :owner
  has_many :subscriptions
  has_many :followed_posts, through: :subscriptions, source: :post, class_name: 'Post', inverse_of: :followers
end

And here are the migrations to support them:

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      # ...
    end
  end
end

class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.integer :owner_id
      # ...
    end
  end
end

class CreateSubscriptions < ActiveRecord::Migration
  def change
    create_table :subscriptions do |t|
      t.integer :post_id
      t.integer :user_id
    end
  end
end

If it weren't for the 'ownership' relation, you could use a has_and_belongs_to_many relationship:

  1. rename the subscriptions migration to posts_users (must be plurals in alphabetical order),
  2. do away with its model entirely, and
  3. have Post.has_and_belongs_to_many :users and User.has_and_belongs_to_many :posts.

In fact, you technically could do that, but having ambiguous names like that is bad practice.

Upvotes: 1

Related Questions