Rails modele birden fazla ilişkilendirme atamak

Öncelikle herkese iyi forumlar.
Ruby on rails ile çalışıyorum ve bir modele birden fazla ilişkilendirme atamak zorundayım örneğin:
User modeli

class User < ApplicationRecord
    has_secure_password
    has_many :members
    has_many :winner
    has_many :creator  
end

Room modeli

class Room < ApplicationRecord
    belongs_to :winner
    belongs_to :creator
    belongs_to :members
end

Burda yapmak istediğim bir oyun yapıyorum ve bu oyunda odalar olucak.
Her bir odanın bir oluşturanı,bir kazananı,ve katılan kullanıcıları olucak ve hepsini User modeli üzerinden oluşturmak istiyorum fakat birtürlü başaramadım.

İlişkilendirmeleri şu şekilde yapmam gerekiyor:
winner => User modelinden has_many ile
creator => User modelinden has_many ile
members => User modelinden has_many ile fakat çok-a-çok ilişkilendirme olucak

Yardımcı olucak hocalarıma şimdiden teşekkürler.

Selamlar.

Aradığın kelimeler class_name ve foreign_key.

Örneğin şurayı bir incele.

Kolay gelsin.

2 Likes

Hocam peki bu alan için ne önerirsiniz bu alanı nasıl halletmeliyim çünkü bu alan kullanıcıları listeleyeceğim alan olucak.

Onun için de aradığın kelime inverse_of.

Yine şurayı inceleyebilirsin.

Rails docs en iyi arkadaşın.

1 Like

Hocam yardımlarınız için çok teşekkür ederim verdiğiniz linkteki gibi herşeyi yaptım ama hata alıyorum kusura bakmayın rails’i yeni öğreniyorum.

User.rb:

class User < ApplicationRecord
  has_many :winner, class_name: "User", foreign_key: "winner_id"
  has_many :creator, class_name: "User", foreign_key: "creator_id"
end

Room.rb

class Room < ApplicationRecord
  belongs_to :winner, class_name: "Room", optional:true
  belongs_to :creator, class_name: "Room", optional:true
end

Modelleri oluşturma şeklim:

$ rails g model User username first_name last_name role game_id:integer password

$ rails g model Room rules:text winner:belongs_to creator:belongs_to online:boolean room_id:integer password

Konsolda denediklerim:

deneme = Room.new do |deneme|
  deneme.rules = "Deneme"
  deneme.password = "a"
  deneme.online = true
  deneme.room_id = 1
end

deneme.winner_id = User.find_by(role: "player").id
deneme.creator_id = User.find_by(role: "janitor").id

Ekran çıktısı:

home/tuncay/.rvm/gems/ruby-3.0.1/gems/sqlite3-1.4.2/lib/sqlite3/database.rb:147:in `initialize': SQLite3::SQLException: no such table: main.creators (ActiveRecord::StatementInvalid)
home/tuncay/.rvm/gems/ruby-3.0.1/gems/sqlite3-1.4.2/lib/sqlite3/database.rb:147:in `initialize': no such table: main.creators (SQLite3::SQLException)

Kurduğun ilişkiler ve veritabanı yapısı hatalı. Uzun uzun açıklamak isterdim ancak şu anda o kadar vaktim yok.

Eğer başka bir arkadaş aradığın cevabı vermezse hafta sonu detaylıca yazacağım @WormerKing

1 Like

Teşekkürler hocam sağolun.

Bir bak bakalım @WormerKing Bana istediğin yapı bu gibi geliyor.

class User < ApplicationRecord
  has_many :rooms
end
class Room < ApplicationRecord
  belongs_to :user
  belongs_to :winner, class_name: 'User', foreign_key: 'winner_id'
  belongs_to :creater, class_name: 'User', foreign_key: 'creater_id'
end

Şöyle kolaylıkla üzerinde dolaşabilirsin.

Şu repodan demo projeyi deneyebilirsin.

Umarım yardımcı olur. İyi günler.

1 Like

Çok teşekkürler hocam bu işimi çözdü ama sadece

burası istediğim gibi çalışmadı onu da create_join_table kullanarak çözdüm.
İsteyenler için kaynak:

Çalışmadı değil senin istediğin o değildi sanırım. Sonradan konuyu okuyacaklar için neden böyle bir şey yaptığını açıkla istersen @WormerKing

Ben repoyu sileceğim çünkü.

1 Like

@sinankeskin aslında hocam sadece members kısmı için belongs_to oluşturmak yerine sizin kodlarınızla beraber bir join_table oluşturdum.Hem bu sayede modeller arası çok-a-çok ilişki kurmuş oldum.

İsteyenler için kodlar:

class User < ApplicationRecord
  has_many :creator_rooms, class_name: "Room", foreign_key: "creator_id", dependent: :destroy
  has_many :winner_rooms, class_name: "Room", foreign_key: "winner_id", dependent: :destroy
  has_and_belongs_to_many :rooms, dependent: :destroy
end
class Room < ApplicationRecord
  belongs_to :winner, class_name: "User", foreign_key: "winner_id", dependent: :destroy
  belongs_to :creator, class_name: "User", foreign_key: "creator_id", dependent: :destroy

  has_and_belongs_to_many :users, dependent: :destroy
end
class CreateJoinTable < ActiveRecord::Migration[6.1]
  def change
    create_join_table :users, :rooms do |t|
      t.index :user_id
      t.index :room_id
    end
  end
end
1 Like