Hartl RoR チュートリアル http://ruby.railstutorial.org/bookを終えたばかりで、ユーザーがグループに参加できる機能を追加しようとしています。私のコードは、次のユーザーのコードに基づいています。グループとユーザーに属するメンバーシップ モデルを使用しています。以下を使用して、rspec でメンバーシップを作成できました。
let(:group) { FactoryGirl.create(:group)}
let(:member) { FactoryGirl.create(:user) }
let(:membership) {group.memberships.build(member_id: member.id, group_id: group.id) }
ただし、実際の運用コードでメンバーシップを作成しようとすると、group.id は常に現在のユーザーのユーザー ID と等しくなります。たとえば、グループ 1 にユーザー 105 として参加しようとすると、サーバーを実行しているターミナルに次の出力が表示されます。
Started POST "/memberships" for 127.0.0.1 at 2013-11-08 21:07:56 -0600
Processing by MembershipsController#create as JS
Parameters: {"utf8"=>"✓", "membership"=>{"group_id"=>"1"}, "commit"=>"Join"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = '342a18004399db9cb75e1a7239dc634b2006e7d6' LIMIT 1
{"utf8"=>"✓", "membership"=>{"group_id"=>"1"}, "commit"=>"Join", "action"=>"create", "controller"=>"memberships"}
Group Load (0.2ms) SELECT "groups".* FROM "groups" WHERE "groups"."id" = ? LIMIT 1
[["id", "1"]]
(0.1ms) begin transaction
SQL (0.7ms) INSERT INTO "memberships" ("created_at", "group_id", "member_id", "updated_at") VALUES (?, ?, ?, ?) [["created_at", Sat, 09 Nov 2013 03:07:56 UTC +00:00, ["group_id", 105], ["member_id", 105], ["updated_at", Sat, 09 Nov 2013 03:07:56 UTC+00:00]]
(2.4ms) commit transaction
Rendered groups/_join.html.erb (2.9ms)
Rendered memberships/create.js.erb (10.3ms)
Completed 200 OK in 32ms (Views: 19.9ms | ActiveRecord: 3.7ms)
グループに参加するためのボタンの HTML.erb パーシャル:
<%= form_for(@group.memberships.build(member_id: current_user.id, group_id: @group.id), remote: true) do |f| %>
<div><%= f.hidden_field :group_id %></div>
<%= f.submit "Join", class: "btn btn-large btn-primary" %>
<% end %>
表示されているページは、グループの表示パスです。
def show
@group=Group.find(params[:id])
@user=current_user
@members=@group.members.paginate(page: params[:page])
end
メンバーシップ コントローラーの作成アクションは次のとおりです。
def create
puts params
@group = Group.find(params[:membership][:group_id])
#Membership.new(member_id: current_user.id, group_id: @group.id)
current_user.join!(@group)
end
メンバーシップ モデルは次のとおりです。
class Membership < ActiveRecord::Base
belongs_to :member, class_name: "User"
belongs_to :group, class_name: "Group"
validates :member_id, presence: true
validates :group_id, presence: true
end
User.join! メソッドは次のとおりです。
def join!(group)
memberships.create!(group_id: group.id, member_id: self.id)
end
ユーザーモデルは次のとおりです。
class User < ActiveRecord::Base
validates :name, presence: true, length: {maximum: 50}
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: {case_sensitive: false }
before_save {email.downcase!}
before_create :create_remember_token
has_secure_password
validates :password, length: { minimum: 6 }
has_many :microposts, dependent: :destroy
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
has_many :memberships, foreign_key: "group_id"
has_many :joined_groups, through: :memberships, source: :group
def following?(other_user)
relationships.find_by(followed_id: other_user.id)
end
def follow!(other_user)
relationships.create!(followed_id: other_user.id)
end
def unfollow!(other_user)
relationships.find_by(followed_id: other_user.id).destroy!
end
def join!(group)
memberships.create!(group_id: group.id, member_id: self.id)
end
def member?(group)
memberships.find_by(group_id: group.id)
end
def leave_group!(group)
memberships.find_by(group_id: group.id).destroy
end
def User.new_remember_token
SecureRandom.urlsafe_base64
end
def feed
Micropost.from_users_followed_by(self)
end
def User.encrypt(token)
Digest::SHA1.hexdigest(token.to_s)
end
private
def create_remember_token
self.remember_token = User.encrypt(User.new_remember_token)
end
end
最後に、グループ 1 にユーザー 1 として参加したところ、グループにユーザー 1 のグラバターが表示されるようになりましたが、グループ 1 に参加させようとした他のユーザーのグラバターは表示されません。