我想创建一个带有邀请系统的应用,用户可以邀请成员加入不同的团队。但我无法让它发挥作用。我有四个模型对象 - User
,Team
,Member (join table between User & Team)
& Invitation
- 这些看起来像这样:
#User
has_many :members
has_many :teams, through: :members
accepts_nested_attributes_for :teams
accepts_nested_attributes_for :members
has_many :sent_invitations, class_name: "Invitation", foreign_key: "sender_id"
has_many :invitations
#Team
has_many :members
has_many :users, through: :members
has_many :invitations
#Invitation
has_one :sender, class_name: "User"
has_one :recipient, class_name: "User"
belongs_to :team
我有ActionMailer
向用户发送邀请,每个Invitation
对象都有一个令牌。当我创建新用户时,我想以安全的方式将受邀用户添加到正确的团队中。我的用户控制器如下所示:
# GET /users/new
def new
@user = User.new
if params[:invitation_token]
@user.email = Invitation.find_by_token(params[:invitation_token]).recipient_email
@invitation = Invitation.where(token: params[:invitation_token])
else
@team = @user.teams.build
end
end
# POST /users
# POST /users.json
def create
@user = User.new(user_params)
respond_to do |format|
if @user.save
sign_in @user
# Private method for adding users to their teams.
add_to_team
[...]
def add_to_team
if @invitation
puts "Should add to team" # But never gets called!
@user.teams << @invitation.team
@user.invitations << @invitation
@user.save!
end
end
似乎add_to_team
中的if语句永远不会评估为true。由于某种原因我的@invitation
是零,我无法弄清楚原因。
有什么想法吗?
更新
尝试将我的@invitation
实例变量改为我的创建操作。像这样:
def create
@user = User.new(user_params)
if params[:invitation_token]
@invitation = Invitation.where(token: params[:invitation_token])
end
#And
def add_to_team
if @invitation
# Never gets called
@user.teams << @invitation.team
@user.invitations << @invitation
puts "Invited by team: #{@invitation.team.name}"
@user.save!
end
end
但是if语句中的代码仍然没有被调用。
答案 0 :(得分:1)
您需要了解的一件重要事情是新操作和创建操作,尽管在同一个控制器中定义会在不同时间调用,因此无法像在Ruby中那样共享任何变量。
共享此类数据有两种方法。一种是向新用户表单添加隐藏字段,并在新操作中将其设置为适当的值。然后从创建操作中访问它。
# new action
@invitation_token = params[:invitation_token]
# in form view
# add hidden field for invitation_token initialized to @invitation_token
# like following
<%= hidden_field_tag :invitation_token, @invitation_token %>
然后,访问params[:invitation_token]
的代码将在创建操作中有效。
或者,使用会话变量从新操作传递令牌以创建操作。
# in new action
if params[:invitation_token]
# other code
session[:invitation_token] = params[:invitation_token]
else
# other code
end
# in create action
if session[:invitation_token]
@invitation = Invitation.where(token: session[:invitation_token])
session[:invitation_token] = nil
end