我在我的Rails 3应用中使用devise_invitable
和devise
。我想让我的用户能够邀请其他用户,并在被邀请者注册之前将这些受邀用户分组。
我的问题是,一旦被邀请者出现并注册(但不使用邀请URL),destroy_if_previously_invited
around_filter会出现,销毁原始用户记录并为用户重新创建新记录,保留邀请数据但不传输user_groups记录。
我想通过搜索与最初邀请的user_id匹配的任何user_group并使用新创建的user_id保存它们来简单地覆盖此around_filter。
我一直收到错误:
LocalJumpError in Users::RegistrationsController#create
no block given (yield)
我的路线如下:
devise_for :users, :controllers => { :registrations => "users/registrations" }
我已将此设置为app / controllers / users / registrations_controller.rb中的覆盖:
class Users::RegistrationsController < Devise::RegistrationsController
around_filter :destroy_if_previously_invited, :only => :create
private
def destroy_if_previously_invited
invitation_info = {}
user_hash = params[:user]
if user_hash && user_hash[:email]
@user = User.find_by_email_and_encrypted_password(user_hash[:email], '')
if @user
invitation_info[:invitation_sent_at] = @user[:invitation_sent_at]
invitation_info[:invited_by_id] = @user[:invited_by_id]
invitation_info[:invited_by_type] = @user[:invited_by_type]
invitation_info[:user_id] = @user[:id]
@user.destroy
end
end
# execute the action (create)
yield
# Note that the after_filter is executed at THIS position !
# Restore info about the last invitation (for later reference)
# Reset the invitation_info only, if invited_by_id is still nil at this stage:
@user = User.find_by_email_and_invited_by_id(user_hash[:email], nil)
if @user
@user[:invitation_sent_at] = invitation_info[:invitation_sent_at]
@user[:invited_by_id] = invitation_info[:invited_by_id]
@user[:invited_by_type] = invitation_info[:invited_by_type]
user_groups = UserGroup.find_all_by_user_id(invitation_info[:user_id])
for user_group in user_groups do
user_group.user_id = @user.id
user_group.save!
end
@user.save!
end
end
end
我也可能只是将这一切都搞错了。任何想法都将不胜感激。
答案 0 :(得分:0)
首先,没有必要再次设置around_filter,因为devise_invitable已经设置了这个。您需要做的就是重新定义UsersController中的方法,然后调用那些方法而不是devise_invitable方法。
其次,看起来你正在将这两种方法结合起来,它们应该保持独立和重写(我的基础是最新版本的devise_invitatable 1.1.1)
尝试这样的事情:
class Users::RegistrationsController < Devise::RegistrationsController
protected
def destroy_if_previously_invited
hash = params[resource_name]
if hash && hash[:email]
resource = resource_class.where(:email => hash[:email], :encrypted_password => '').first
if resource
@old_id = resource.id #saving the old id for use in reset_invitation_info
@invitation_info = Hash[resource.invitation_fields.map {|field|
[field, resource.send(field)]
}]
resource.destroy
end
end
end
def reset_invitation_info
# Restore info about the last invitation (for later reference)
# Reset the invitation_info only, if invited_by_id is still nil at this stage:
resource = resource_class.where(:email => params[resource_name][:email], :invited_by_id => nil).first
if resource && @invitation_info
resource.invitation_fields.each do |field|
resource.send("#{field}=", @invitation_info[field])
end
### Adding your code here
if @old_id
user_groups = UserGroup.find_all_by_user_id(@old_id)
for user_group in user_groups do
user_group.user_id = resource.id
user_group.save!
end
end
### End of your code
resource.save!
end
end