Sonny Black
Sonny Black

Reputation: 1617

has_and_belongs_to_many association confusion

So I have an application that has a blog model,and a user model.

Now users can subscribe to many different blogs, and users can also create many of their own blogs.

What would the association look like?

Right now my models look like the following:

Blog.rb:

class Blog < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_many :posts

end

User.rb:

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_and_belongs_to_many :blogs     

  validates :email, uniqueness: true, presence: true
  validates_presence_of :password, on: :create         

end

the user table has a blog_id:integer field, and the blog has a user_id:integer field.

Is this right?

And how would the commands work? I.E:

u = User.last
b = u.blogs.build(title: "bla")
b.user (shows the owner of the blog)
b.users (shows the users that have subscribed to the blog)

Ultimately, I'd like to allow users to subscribe to other peoples blogs, and create their own.

Upvotes: 0

Views: 40

Answers (1)

fresh5447
fresh5447

Reputation: 1340

You are going to want to add a third model 'Subscriptions'. Then you are going to want to use the 'has_many_through:' association. Please read this section of the rails guides for a detailed example. http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association.

After you create the associations you are going to want to do something along these lines: 1) make sure you nest the 'subscriptions' routes underneath the blog route properly.

resources :blogs, only: [] do
    resources :subscriptions, only: [:create, :destroy]

2) Create a _subscription.html.erb partial in app/views/subscriptions

3) Render the partial in blogs#show

<%= render partial: 'subscriptions/_subscription, locals: {blog: @blog}

4) Add the ability to add (create) a subscription in the partial: (this is only to add subscription, you will want to also add ability to remove)

 <%= link_to [blog, Subscription.new], class: 'btn btn-primary', method: :post do %>
   <i class="glyphicon glyphicon-star"> </i>&nbsp; Subscribe
 <% end %>

5) Add 'create method' to subscriptions_controller.rb

   def create
     @blog = Blog.find(params[:blog_id])
     subscription = current_user.subscriptions.build(blog: @blog)

     if subscription.save
       # Add code
     else
       # Add code
     end
   end

This should be enough direction to get you to the finish line. Good luck :)

Upvotes: 2

Related Questions