2016-09-04 9 views
0

ゴール:ユーザは、ユーザアカウント(作成者)を作成し、その後グループを作成することができます。各ユーザーはbelongs_toグループとグループhas_manyユーザーのみです。Rails - belongs_to has_many関連エラー

マイグレーションを作成して実行した後 - ユーザーを作成しようとすると、次のエラーが表示されます。「1エラーでこのユーザーを保存できませんでした:グループは存在しています」

明らかに、現在のセットアップでは、ユーザー作成時にgroup_idが存在する必要があります。

  1. この状況ではbelongs_to/has_manyの関係は正しいですか?これはhas_oneですか?
  2. 両方の移行に外部キー属性が必要ですか?
  3. @group.user_id = current_user.idGroupsController#createに設定すると、作成するユーザーをグループに割り当てるのに適していますか?グループモデルでコールバックを使用してこれを実行しようとしましたが、変数current_userにアクセスできませんでした。
  4. 私はまた、(データベースレベルで)ユーザが1つのグループにしか属していないことを強制したいと思います - これはスキーマ内でunique => trueを使用して達成されていますか?
  5. グループにユーザーが必要であることを(データベースレベルで)どのように強制できますか?

。セットアップするには

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

「グループ」には多くの「ユーザー」があると言っています。だから、あなたのuserテーブルに 'group_id'があるはずです。グループテーブルにはありません。そして、あなたは 'current_user.group.new(group_params)'のような 'Group'を作成することができます – Emu

答えて

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

ユーザーが1つのグループにのみ属することができますが、グループは多くのユーザーを持っている、あなたは正しい軌道に乗っている関係。

class Group < ActiveRecord::Base 
    has_many :users 
end 

class User < ActiveRecord::Base 
    belongs_to :group 
end 

belongs_tousers.group_idとして外部キー列を配置します。 has_oneを使用すると、groups.user_id列に配置され、1対1のマッピングしか許可されません。グループには1人のユーザーしか存在できません。

  1. Should both migrations have a foreign key attribute?

いいえ - usersテーブルには、外部キーが含まれている必要があります。 AddUserReferenceToGroupを削除するか、プロダクションにプッシュした場合はgroups.user_id列を削除する別の移行を作成する必要があります。

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

ません - ないグループ - group_id列を使用すると、ユーザーテーブルを更新する必要がusers列上にあるため。

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?

なし - usersテーブルの行は、ユーザが、とにかく一つのグループにのみ属することができgroups_id列に1つのIDを有することができるからです。 unique => trueを使用すると、users.groups_id列の一意性インデックスが作成され、単一のユーザーのみがグループに関連付けられます。

これは実際には可能ではありません。ユーザーをグループに関連付けるには、最初にグループをデータベースに挿入して、IDを割り当てておく必要があります。

ソフトウェアレベルで検証を追加すると、ユーザーがいないためグループを有効にできず、グループが永続化されていないためグループに関連付けることができないという「鶏VS卵」の状況も発生します。

ただし、NOT NULLという外部キー列を宣言することによって、belongs_toの最後に制約を設定できます。

関連する問題