设计用户是否存在然后更新

时间:2015-05-12 16:36:25

标签: ruby-on-rails validation devise

我在另一个视图中有一个用户表单,非常适合创建用户。我希望人们完成此表格,即使他们已经是用户。

如果他们已经是用户,我希望表单更新他们的位置,如果他们输入任何内容并保存。

用户表单

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>

<div class="form-group">
  <%= f.label :location, "Where are you based?" %><br />
  <%= f.text_field :location, placeholder: "E.g. London", class: "full-width form-field" %>
</div>

<div class="form-group">
  <%= f.label :email, "What is your email?" %>  
  <%= f.email_field :email, placeholder: "Enter email", class: "full -width form-field" %>
</div>

<div class="actions">
    <%= f.button "GO", class: "btn btn-1R btn-orange full-width", id: "submit_button" %>
</div>

<% end %>

我以为我可以在模型中执行before_validation方法来检查用户是否存在,如果没有则创建一个。这是正确的吗?

before_validation :check_user, :on => :create

def check_user 
    @user = User.where(email: self.email).first
    unless @user.blank?
        @user.update_attributes(:location => self.location)
        @user.save
    else
        puts 'NEW USER'
    end
end

这仍然是“已经发送电子邮件”错误。

如何杀死'create'方法并在此处引发更新方法?或者我完全错了吗?

2 个答案:

答案 0 :(得分:0)

我认为您希望避免在模型中创建记录。您似乎要做的就是将注册#create与注册#update结合起来。您可以通过覆盖注册控制器中的devise's registrations#create method来完成此操作。因此,您可以做的是在构建新资源之前检查您的用户是否已存在。像这样......:

def create
  if user = User.where(email: sign_up_params[:email]).first
    user.update_attributes(location: sign_up_params[:location])
    self.resource = user
  else
    self.resource = resource_class.new_with_session(sign_up_params || {}, session)
  end

  resource.save
  yield resource if block_given?
  if resource.persisted?
    if resource.active_for_authentication?
      set_flash_message :notice, :signed_up if is_flashing_format?
      sign_up(resource_name, resource)
      respond_with resource, location: after_sign_up_path_for(resource)
    else
      set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
      expire_data_after_sign_in!
      respond_with resource, location: after_inactive_sign_up_path_for(resource)
    end
  else
    clean_up_passwords resource
    set_minimum_password_length
    respond_with resource
  end
end

答案 1 :(得分:0)

我设法通过将方法移动到控制器并调用

来解决此问题
 before_action :check_user, only: [:create]

def check_user
  @user = User.where(email: sign_up_params[:email]).first
  unless @user.blank?
    @user.update_attributes(:location => sign_up_params[:location])
    @user.save
    redirect_to(:back) and return
  else
    puts 'NEW USER'
  end
end

redirect_to(:back) and return是钉牢的。 :)