Remis07
Remis07

Reputation: 377

How to make a one to many relation in rails

here is what i want to have:

-table Announce (id, title, description,..) 

-table city (id, name) 

-table Annouce_city (idAnnouce, idCity) 

Once an annouce is created, a line is automatically added to the Annouce_city table containing the Announce id and the id city selected

So for now i succeeded in creating a one_to_many relation but it's not what i want, since the Annouce_city table should have an announce one time but a city many times.

thanks!

class City < ActiveRecord::Base
validates :name, presence: true, length: { minimum: 3, maximum: 25 }
validates_uniqueness_of :name
end

class Annonce < ActiveRecord::Base
belongs_to :user
validates :marque, presence: true, length: {minimum: 2, maximum: 35 }
validates :couleur, presence: true, length: {minimum: 2, maximum: 35 }
validates :user_id, presence: true
mount_uploaders :imgs, ImgUploader
serialize :imgs, JSON
end

class AnnonceCity < ActiveRecord::Base
belongs_to :annonce
belongs_to :city
end

Upvotes: 2

Views: 47

Answers (1)

Richard Peck
Richard Peck

Reputation: 76774

has_many :through:

#app/models/announcement.rb
class Announcement < ActiveRecord::Base
   #id | title | description | etc
   has_many :announcement_cities
   has_many :cities, through: :announcement_cities
end

#app/models/announcement_city.rb
class AnnouncementCity < ActiveRecord::Base
   #id | annoucement_id | city_id
   belongs_to :announcement
   belongs_to :city
end

#app/models/city.rb
class City < ActiveRecord::Base
   #id | name | etc
   has_many :announcement_cities
   has_many :cities, through: :announcement_cities  
end

The above will give you the ability to create an announcement for any number of cities (which is basically what you have already):

#app/controllers/announcements_controller.rb
class AnnouncementsController < ApplicationController
   def create
      @city         = City.find params[:city_id]
      @announcement = @city.announcements.new announcement_params
      @announcement.save
   end
end

--

If you wanted to create one announcement, and have that replicated for every city, you'll need to make a custom method:

#config/routes.rb
resources :announcements do
   post :all_cities, on: :collection #-> url.com/announcements/all_cities
end

#app/controllers/announcements_controller.rb
class AnnouncementsController < ApplicationController
   def all_cities
      @announcement = Announcement.new announcement_params
      if @announcement.save
         @cities = City.all
         @cities.each do |city|
            city.announcements << announcement
         end
      end
   end
end

Upvotes: 1

Related Questions