我对Rails非常陌生并且正在努力奋斗。
我的用户遵循基本的注册,编辑过程。
我的情况是用户可以“部分注册”,即数据库中的用户电子邮件地址,其中包含随机密码,因为他们通过现有用户的邀请流程放入其中。
当数据库中已经技术上存在的受邀用户尝试注册时,我会收到“电子邮件已存在”,因为我确实对用户对象应用了唯一性检查,并在表上添加了唯一索引。
我确实将其关闭并在create方法中使用if语句来查看用户是否存在并检查其他值是执行更新还是更新并保存。忽略了所有if条件并创建了新用户。
我想要做的是使用“创建”用户的相同注册表单,使用输入的密码和名称更新现有的“部分注册”用户(如果存在)(电子邮件地址检查),并将其他数据库标志设置为真正。如果用户确实存在但条件未满足,则加载“忘记密码”页面,或者如果用户是新用户,则创建并保存。
关于如何实现上述目标的任何帮助或建议都将是明智的。
由于
维基
这是我的设置:
用户类
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :email, :name, :password, :password_confirmation, :tandc
email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :name, :presence => true,
:length => { :maximum => 50 }
validates :email, :presence => true,
:format => {:with => email_regex },
:uniqueness => { :case_sensitive => false }
validates :password, :presence => true,
:confirmation => true,
:length => { :within => 6..40 }
validates :tandc, :presence => true
before_save :encrypt_password
.
.
.
end
我有一个带有以下
的UsersController def new
@user = User.new
@title = "Sign Up"
end
def create
if @user.save
sign_in @user
redirect_to @user
else
@title = "Sign up"
render 'new'
end
end
def update
if @user.update_attributes(params[:user])
redirect_to @user
else
@title = "Edit"
render 'edit'
end
end
.
.
.
我有意见: 用户&gt; new.html.erb
<%= form_for(@user, :html => { :class => "validateUser", :name =>"edit_user"}) do |f| %>
.
.
.
form stuff here
.
.
.
<% end %>
和用户&gt; edit.html.erb
<%= form_for(@user, :html => { :class => "validateUser", :name =>"edit_user"}) do |f| %>
.
.
.
form stuff here
.
.
.
<% end %>
我的用户路线如下
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
答案 0 :(得分:2)
快速但不优雅的解决方案可能是:
def create
if user = User.find_by_email(params[:user][:email])
if user.part_registered?
user.update_attributes(params[:user])
user.save
sign_in user
redirect_to user
else
@user = User.new(params[:user])
if @user.save
# just to trigger the error messages ...
else
@title = "Sign up"
render 'new'
end
end
else
@user = User.new(params[:user])
if @user.save
sign_in @user
redirect_to @user
else
@title = "Sign up"
render 'new'
end
end
end
抱歉,我现在没时间优化这些条件
答案 1 :(得分:2)
首先,不会删除用户电子邮件中的唯一索引。如果您将它用作模型的自然键,即使用它登录,则需要它是唯一的。
问问自己,邀请的重点是什么?我有一个潜在的怀疑,创建一个新用户并不是你想要的应用程序做什么...如果用户从未接受邀请函上的邀请者怎么办?
相反,您可以使用用户的电子邮件和邀请者创建一个邀请对象(如果这是邀请点。)然后,您可以提供一个链接,将邀请作为参数传递:<%= link_to new_user_url, email: invitation_email_here %>
并放入例如,链接到受邀用户的电子邮件。
在users/new.html.erb
中,您可以传递值以使用电子邮件预先填写表单:
<%= f.email_field :email, value: params[:email] %>
另外,我会把你的表格放在一边,不要重复自己。
form_for的工作方式,如果@user是new,它将发出一个POST请求,其中填充了UsersController的create
操作的值。如果@user是现有模型,它将使用现有值填充表单,向UsersController的update
操作发出PUT请求。
长话短说edit
和new
次观看次数相同。要简单地显示相同的表单,请在users / veiws目录中进行部分显示。
<!-- app/views/users/_form.html.erb -->
<%= form_for(@user, html: { class: "validateUser" }) do |f| %>
...
<% end %>
然后在您要放置表单的视图中,放置<%= render 'users/form' %>
答案 2 :(得分:2)
您可以使用User.find_or_initialize_by_email(:email => params[:user_email])
行的内容来获取User对象。
基本上,find_or_initialize
将尝试从数据库中获取用户,如果它无法获取任何内容,它将创建一个您可以稍后保存的新用户。
获取User对象后,可以对其字段执行任何操作,然后将结果保存到数据库中(更新旧条目或创建新条目)。
(注意:如果要检查用户以前是否存在,请对.persisted?
返回的对象使用find_or_initialize
,这将返回一个布尔值,告诉您它是否已存在于数据库中。 )
答案 3 :(得分:2)
当有人在网站上注册时,您可以在登录之前发送帐户验证电子邮件。该电子邮件包含一个带有系统生成令牌的链接(例如“User.token”)。当他们点击链接时,您的verification_controller会通过令牌检索用户并让他们设置密码。
# In class User < ActiveRecord::Base
# Give the user a unique, random token
user.token = SecureRandom.urlsafe_base64(20)
# In class VerificationsController < ApplicationController
# Retrieve the user with their token
@user = User.find_by_token(params[:token])
现在让我们考虑你的情况。当受邀用户在接受邀请之前尝试注册时,您仍然可以发送帐户验证电子邮件。现在他们有两封电子邮件:1)来自邀请,2)来自他们的注册。没关系......他们只需点击链接并设置密码即可。
您可能希望使令牌过期,因为它提供了访问帐户的方法。一个流行的身份验证框架AuthLogic有一个password resets tutorial,它很有帮助。它显示了一种类似的技术,可能会为您的手工构建解决方案提供一些想法。
答案 4 :(得分:1)
您可以尝试使用users_controller.rb
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
respond_to do |format|
if @user.update_attributes(params[:user])
format.html { redirect_to @collection, notice: 'User was successfully updated.'}
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
添加指向视图的链接
<%= link_to content_tag(:span, "Edit"), edit_user_path(@user), :class => 'edit' %>
在new.html.erb中删除表单并添加
<%= render 'form' %>
(这将呈现您将添加表单代码的部分内容)
创建_form.html.erb并将表单代码添加到此
然后创建您的edit.html.erb视图并添加代码
<%= render 'form' %>