簡體   English   中英

僅更新Rails模型中的某些屬性

[英]Updating only some attributes in a rails model

我正在嘗試創建一個帳戶管理頁面,您可以在其中更新您的顯示名稱,電子郵件,密碼和其他內容。 我想允許用戶僅更新其部分信息,而如果未更改的信息無效,則模型拒絕更改。 我只需要更新模型的一部分,特別是無需輸入密碼和確認即可更新帳戶詳細信息。

使用單個表格要求用戶在更新詳細信息時更改其密碼。 我嘗試將帳戶詳細信息分為“個人資料”和“安全”表格,希望在更新某人的姓名時不會發送空密碼,但是該模型拒絕更改,並指出密碼丟失。 但是,使用兩種形式的設置僅更新密碼似乎可以正常工作。

我正在尋找一種通用的解決方案,該解決方案可以讓我將來擴展以僅更新特定的字段子集(將2FA添加到安全性部分將要求用戶更改其密碼以按原樣更新其2FA密鑰)。

我正在使用的唯一外部寶石是“ 我曾經擁有”寶石和更新的email_check寶石

我當前的代碼是:
routes.rb

Rails.application.routes.draw do
  # ...
  get '/account', to: 'account#index'
  post '/account', to: 'account#update'

  root 'application#home'
end

賬戶模型

class Account < ApplicationRecord
  self.primary_key = :id

  before_validation do
    self.id.to_s.downcase! # lowercase the id
    self.email.to_s.downcase! # lowercase the email
  end

  validates :id,
            presence: true,
            length: { minimum: 5, maximum: 32 },
            uniqueness: true,
            format: { with: /\A[a-z0-9-]*\z/, message: 'Only lowercase alphabet, numbers and dash allowed.' }
  validates :name,
            presence: true,
            length: { minimum: 2, maximum: 50 }
  validates_email_strictness :email,
                  message: 'Something about that email doesn\'t look right... Make sure the spelling is right or try another?'

  has_secure_password
  validates :password,
            presence: true,
            not_pwned: true,
            format: { with: /\d/ },
            length: { minimum: 8 }
  attr_accessor :password_confirmation

  attr_accessor :remember_token
end

account_controller.rb

class AccountController < ApplicationController
  def index
    if logged_in?
      @account = current_account
    else
      flash[:danger] = "You must be logged in to do that!"
      redirect_to '/account/login'
    end
  end
  def update
    @account = current_account
    # TODO security concerns or otherwise when receiving only profile, security, etc fields
    if @account.update_attributes(account_params)
      flash.now[:success] = 'Update success!'
    else
      flash.now[:danger] = 'Something went wrong!'
    end
    render 'index'
  end

  private def account_params
    params.require(:account).permit(:id,:name,:email,:password,:password_confirmation)
  end
end

和account / index.html.erb

<% provide(:title,'Manage Account') %>

<h1>Manage Account</h1>

<%= render 'shared/error_messages' %>

<h3>Profile & Contact Info</h3>
<div>
  <p>Account ID</p>
  <input disabled value="<%= @account.id %>">
  <form action="/account" method="post">
    <input name="utf8" type="hidden" value="&#x2713;" />
    <%= hidden_field_tag :authenticity_token, form_authenticity_token %>

    <p>Name</p>
    <input name="account[name]" value="<%= @account.name %>">
    <p>Email</p>
    <input name="account[email]" value="<%= @account.email %>" type="email">

    <button type="submit">Submit</button>
  </form>
</div>
<h3>Password & Security</h3>
<form action="/account" method="post">
  <input name="utf8" type="hidden" value="&#x2713;" />
  <%= hidden_field_tag :authenticity_token, form_authenticity_token %>

  <p>New Password</p>
  <input name="account[password]" type="password">
  <p>Confirm New Password</p>
  <input name="account[password_confirmation]" type="password">

  <button type="submit">Submit</button>
</form>

如果僅在輸入密碼后才想驗證密碼字段,請按以下條件使用proc對象。 這將允許其他字段更新,而與密碼字段無關

  validates :password,
            presence: true,
            not_pwned: true,
            format: { with: /\d/ },
            length: { minimum: 8 }, unless: Proc.new { |account| account.password.blank? }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM