2016-09-04 9 views
0

Ziel: Ein Benutzer kann ein Benutzerkonto (Gerät) und anschließend eine Gruppe erstellen. Jeder Benutzer nur belongs_to eine Gruppe und eine Gruppe has_many Benutzer.Rails - gehören zu has_many association error

Nach dem Erstellen und Ausführen der Migrationen - Wenn ich versuche, einen Benutzer zu erstellen, wird der folgende Fehler angezeigt: "1 Fehler beim Speichern dieses Benutzers: Gruppe muss vorhanden sein".

Offensichtlich möchte das aktuelle Setup eine group_id beim Erstellen eines Benutzers existieren.

  1. Ist eine assigns_to/has_many-Zuordnung für diese Situation korrekt? Sollte das ein has_one sein?
  2. Sollten beide Migrationen ein Fremdschlüsselattribut haben?
  3. Ist die Einstellung @group.user_id = current_user.id in GroupsController#create eine geeignete Methode, um den Erstellungsbenutzer der Gruppe zuzuweisen? Ich habe versucht, dies im Groups-Modell zu tun, indem ich einen Callback benutzte, aber ich konnte nicht auf die Variable current_user zugreifen.
  4. Ich möchte auch (auf der Datenbankebene) erzwingen, dass ein Benutzer nur zu einer Gruppe gehören kann - Wird dies erreicht mit unique => true im Schema?
  5. Wie kann ich (auf Datenbankebene) erzwingen, dass eine Gruppe einen Benutzer haben muss?

.

class Group < ApplicationRecord 
    has_many :users 
    validates :users, presence: true 
end 


class User < ApplicationRecord 
    ... 
    belongs_to :group 
    ... 
end 


class GroupsController < ApplicationController 
... 
    def create 
     @group = Group.new(group_params) 
     @group.user_id = current_user.id 
     ... 
    end 
... 

private 
... 
    def group_params 
     params.require(:group).permit(:name, :user_id) 
    end 
... 

end 

class AddGroupReferenceToUser < ActiveRecord::Migration[5.0] 
    def change 
    add_reference :users, :group, foreign_key: true 
    end 
end 

class AddUserReferenceToGroup < ActiveRecord::Migration[5.0] 
    def change 
    add_reference :groups, :user, foreign_key: true 
    end 
end 

ActiveRecord::Schema.define(version: 20160903125553) do 

    create_table "groups", force: :cascade do |t| 
    t.string "name" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.integer "user_id" 
    t.index ["user_id"], name: "index_groups_on_user_id" 
    end 

    create_table "users", force: :cascade do |t| 
... 
    t.integer "group_id" 
    t.index ["email"], name: "index_users_on_email", unique: true 
    t.index ["group_id"], name: "index_users_on_group_id" 
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true 
    end 
end 
+0

Sie sagen "Gruppe" hat viele 'Benutzer'. Es sollte also eine 'group_id' in Ihrer Benutzertabelle geben. Nicht in der Gruppentabelle. Und Sie können eine 'Gruppe' wie' aktuelle_benutzer.gruppe.neu (group_params) 'erstellen – Emu

Antwort

0
  1. Is a belongs_to/has_many association correct for this situation? Should this be a has_one?

eine Beziehung zu Aufbau, in dem ein Benutzer nur zu einer einzigen Gruppe gehören, können aber Gruppen haben viele Benutzer dann sind Sie auf dem richtigen Weg sind.

class Group < ActiveRecord::Base 
    has_many :users 
end 

class User < ActiveRecord::Base 
    belongs_to :group 
end 

belongs_to Orte der Fremdschlüsselspalte als users.group_id. Mit würde es auf groups.user_id Spalte platzieren, die nur eine Eins-zu-eins-Zuordnung erlauben würde - eine Gruppe könnte nur einen einzigen Benutzer haben.

Nein - nur die Tabelle users sollte einen Fremdschlüssel enthalten. Die AddUserReferenceToGroup sollte entfernt werden oder Sie sollten eine andere Migration schreiben, die die groups.user_id Spalte entfernt, wenn Sie es in die Produktion verschoben haben. Kein

  1. Is setting @group.user_id = current_user.id in GroupsController#create a suitable way to assign the creating user to the group?

- da die group_id Spalte auf der users Spalte müssen Sie die Benutzer-Tabelle aktualisieren - keine Gruppen.

if @group.save 
    current_user.update(group: @group) 
end 
  1. I would also like to enforce (at the database level) that a user can only belong to one group - Is this achieved using unique => true in the schema?

Nein - da eine Reihe auf der users Tabelle nur eine ID in der groups_id Spalte kann ein Benutzer haben kann nur irgendwie zu einer Gruppe gehört. Die Verwendung von unique => true würde einen Eindeutigkeitsindex für die users.groups_id-Spalte erstellen, der nur die Zuordnung einzelner Benutzer zu einer Gruppe ermöglichen würde.

  1. How can I enforce (at the database level) that a group must have a user?

Dies ist eigentlich nicht möglich. Um einen Benutzer einer Gruppe zuordnen zu können, müssen Sie die Gruppe zuerst in die Datenbank einfügen, damit ihr eine ID zugewiesen wird.Wenn eine Validierung auf der Softwareebene hinzugefügt wird, wird auch eine Situation "Huhn gegen Ei" erstellt, in der eine Gruppe nicht gültig sein kann, da keine Benutzer vorhanden sind und ein Benutzer keiner Gruppe zugeordnet werden kann, da sie nicht beibehalten wird.

Sie können jedoch eine Einschränkung für das belongs_to-Ende einrichten, indem Sie die Fremdschlüsselspalte als NOT NULL deklarieren.