在模型中访问 current_user(或其他一些解决方法)
Access current_user in model (or some other workaround)
我已经阅读了几个关于这个主题的 SO 链接。即使您可以破解它以在模型中获得 current_user,您也不应该这样做。那么,我的情况有哪些选择?
我正在使用 devise_invitable gem,其中一个命令是 User.invite!({:email => email}, current_user)
,它存储邀请用户的人 (current_user
)。我想知道这些信息。
目前邀请用户加入私人群组,这个过程在我的group.rb
模型中处理:
# group.rb
def user_emails
end
def user_emails=(emails_string)
emails_string = emails_string.split(%r{,\s*})
emails_string.each do |email|
user = User.find_for_authentication(email: email)
if user
self.add user
GroupMailer.welcome_email(user)
else
User.invite!(email: email) # But I want this: User.invite!({:email => email}, current_user)
user = User.order('created_at ASC').last
self.add user
end
end
end
如果相关,它只是一个 text_area 接收这些电子邮件进行处理:
# groups/_form.html.erb
<%= f.text_area :user_emails, rows: 4, placeholder: 'Enter email addresses here, separated by comma', class: 'form-control' %>
不用重新安排太多,我怎样才能运行User.invite!({:email => email}, current_user)
在这个过程中,让这个有用的信息(谁被谁邀请)存储在我的数据库里呢?非常感谢!
更新:
在@Mohamad 的帮助下,我成功了。
# group.rb
def emails
end
def invite_many(emails, inviter)
emails.split(%r{,\s*}).each do |email|
if user = User.find_for_authentication(email: email)
add user
GroupMailer.group_invite user
else
add User.invite!({:email => email}, inviter)
end
end
end
# groups_controller.rb
def update
@group = Group.friendly.find(params[:id])
if @group.update_attributes(group_params)
emails = params[:group][:emails]
@group.invite_many(emails, current_user) # also put this in #create
redirect_to @group
else
flash[:error] = "Error saving group. Please try again."
render :edit
end
end
然后我的用户模型中什么也没有,因为 User.invite 已经由 devise_invitable 定义,我不需要做任何其他事情。这个过程现在运行良好!
你可以存储全局范围的current_user,比如@current_user,它可以在会话控制器中分配,所以在模型中你将只是@current_user作为当前用户应用程序。
如果您从控制器调用 user_emails()
(我猜您一定是在收到要传入 emails_string
的表单的地方),您可以传入current_user
:
user_emails(emails_string, current_user)
并更改user_emails
以接收它:
def user_emails=(emails_string, current_user)
您的代码存在一些细微的问题。在您尝试添加上次创建的用户的代码的 else
分支上存在潜在的竞争条件。我也不确定你是否需要一个 setter 方法,除非你在 Group
.
的实例中从其他地方访问 emails
按照其他人的建议,将当前用户作为控制器的参数传递。我不确定 invite!
是如何实现的,但假设它 returns 是一个用户,您可以大大重构您的代码。
我会这样做:
def invite_many(emails, inviter)
emails.split(%r{,\s*}).each do |email|
if user = User.find_for_authentication(email: email)
add user
GroupMailer.welcome_email user
else
add User.invite!(email, inviter)
end
end
end
# controller
@group.invite_many(emails, current_user)
# User.invite
def invite(email, inviter)
# create and return the user here, and what else is necessary
end
我已经阅读了几个关于这个主题的 SO 链接。即使您可以破解它以在模型中获得 current_user,您也不应该这样做。那么,我的情况有哪些选择?
我正在使用 devise_invitable gem,其中一个命令是 User.invite!({:email => email}, current_user)
,它存储邀请用户的人 (current_user
)。我想知道这些信息。
目前邀请用户加入私人群组,这个过程在我的group.rb
模型中处理:
# group.rb
def user_emails
end
def user_emails=(emails_string)
emails_string = emails_string.split(%r{,\s*})
emails_string.each do |email|
user = User.find_for_authentication(email: email)
if user
self.add user
GroupMailer.welcome_email(user)
else
User.invite!(email: email) # But I want this: User.invite!({:email => email}, current_user)
user = User.order('created_at ASC').last
self.add user
end
end
end
如果相关,它只是一个 text_area 接收这些电子邮件进行处理:
# groups/_form.html.erb
<%= f.text_area :user_emails, rows: 4, placeholder: 'Enter email addresses here, separated by comma', class: 'form-control' %>
不用重新安排太多,我怎样才能运行User.invite!({:email => email}, current_user)
在这个过程中,让这个有用的信息(谁被谁邀请)存储在我的数据库里呢?非常感谢!
更新:
在@Mohamad 的帮助下,我成功了。
# group.rb
def emails
end
def invite_many(emails, inviter)
emails.split(%r{,\s*}).each do |email|
if user = User.find_for_authentication(email: email)
add user
GroupMailer.group_invite user
else
add User.invite!({:email => email}, inviter)
end
end
end
# groups_controller.rb
def update
@group = Group.friendly.find(params[:id])
if @group.update_attributes(group_params)
emails = params[:group][:emails]
@group.invite_many(emails, current_user) # also put this in #create
redirect_to @group
else
flash[:error] = "Error saving group. Please try again."
render :edit
end
end
然后我的用户模型中什么也没有,因为 User.invite 已经由 devise_invitable 定义,我不需要做任何其他事情。这个过程现在运行良好!
你可以存储全局范围的current_user,比如@current_user,它可以在会话控制器中分配,所以在模型中你将只是@current_user作为当前用户应用程序。
如果您从控制器调用 user_emails()
(我猜您一定是在收到要传入 emails_string
的表单的地方),您可以传入current_user
:
user_emails(emails_string, current_user)
并更改user_emails
以接收它:
def user_emails=(emails_string, current_user)
您的代码存在一些细微的问题。在您尝试添加上次创建的用户的代码的 else
分支上存在潜在的竞争条件。我也不确定你是否需要一个 setter 方法,除非你在 Group
.
emails
按照其他人的建议,将当前用户作为控制器的参数传递。我不确定 invite!
是如何实现的,但假设它 returns 是一个用户,您可以大大重构您的代码。
我会这样做:
def invite_many(emails, inviter)
emails.split(%r{,\s*}).each do |email|
if user = User.find_for_authentication(email: email)
add user
GroupMailer.welcome_email user
else
add User.invite!(email, inviter)
end
end
end
# controller
@group.invite_many(emails, current_user)
# User.invite
def invite(email, inviter)
# create and return the user here, and what else is necessary
end