0

我想创建一个带有邀请系统的应用程序,用户可以在其中邀请成员加入不同的团队。但我无法让它工作。我有四个模型对象 - 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

似乎我的 if 语句add_to_team永远不会评估为真。出于某种原因,我@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 语句中的代码仍然没有被调用。

4

1 回答 1

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
于 2014-05-31T15:44:42.100 回答