【问题标题】:How to update only part of attributes, not all, in rails如何在rails中只更新部分属性,而不是全部
【发布时间】:2011-11-01 12:25:43
【问题描述】:

我有一个用于更新某些属性的编辑表单。但它试图编辑所有属性,因此我有验证错误。

我的表单(编辑视图)

#person_info.fl_l
  - if @user.errors.any?
    .error_explanation
      %h2 Form is invalid
      %ul
        -for message in  @user.errors.full_messages
          %li= message


  =form_for @user do |f|
    %p
      Birthday:
      %br
      = f.date_select(:birthday,:start_year => 1940)
    %p
      Name:
      %br
      = f.text_field :name, :value=>@user.name
    %p
      Surname:
      %br
      = f.text_field :surname, :value=>@user.surname
    %p
      Nickname:
      %br
      = f.text_field :nickname, :value=>@user.surname       
    %p
      About Myself:
      %br
      = f.text_area :about_myself, :value=>@user.about_myself
    %p
      = f.submit "Update"

我的更新和编辑操作:

def edit
      @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
      redirect_to @user
    else
      render 'edit'
    end
  end

当我提交表单时,它会输出验证错误,例如:“密码不能为空”

那么,如何只更新部分属性,而不是全部?我不想更新密码。

我的用户模型

class User < ActiveRecord::Base

  has_many :posts
  has_many :sent_messages, :class_name => "Message", :foreign_key => "sender_id"
  has_many :received_messages, :class_name => "Message", :foreign_key => "receiver_id"
  attr_accessible :name, :email, :password, :password_confirmation
  has_secure_password
  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}


  before_create { generate_token(:auth_token) }

  def send_password_reset
    generate_token(:password_reset_token)
    self.password_reset_sent_at = Time.zone.now
    save!
    UserMailer.password_reset(self).deliver
  end

  def generate_token(column)
    begin
      self[column] = SecureRandom.urlsafe_base64
    end while User.exists?(column => self[column])
  end
end

【问题讨论】:

  • 你能解决这个问题吗?我有完全相同的问题:S

标签: ruby-on-rails ruby ruby-on-rails-3.1


【解决方案1】:

从参数哈希中删除它

params.delete(:password)

或者构建你自己的哈希发送到更新。

【讨论】:

  • 我添加了 params.delete(:password) 来更新操作,但它不起作用,我有密码存在验证,它输出错误
  • “或者构建你自己的哈希发送到更新。”我是新手,笨蛋知道如何在我的情况下做到这一点(
【解决方案2】:

结帐Authentication in Rails 3.1 以简化您的身份验证。它从您的模型中取出大量代码。

然后,我注意到:如果某个字段由于某种原因从表单中隐藏,rails 不会在 params 哈希中传递它以进行更新。因此,您可以在表单中使用隐藏字段。我就是这样解决我的问题的。

【讨论】:

    【解决方案3】:

    我通过附加解决了这个问题

    ,:on => :create
    

    到我的 validates_presence_of 和 validates_length_of 行。

    【讨论】:

    • 如果您不想传入密码来更新属性,这就是您想要的。
    【解决方案4】:

    我相信你的模型在当前状态下是无效的......你没有发送密码,所以 Rails 没有触及那个属性。

    在 Rails 控制台中,测试:

    user = User.find(whatever_the_id_is)
    puts user.valid?
    puts user.errors.inspect
    

    我的假设是它无效 --- 由于缺少密码。

    【讨论】:

    • 我在问题中添加了用户模型
    • 是的,它是无效的,但它怎么可能呢?因为在我的注册表单中可以正常工作,并且里面有密码输入
    • 如果模型是在你添加密码属性之前创建的,那么它是无效的,但新模型是有效的。
    • 你能解释的更准确吗?
    • 如果您运行向模型添加“密码”的迁移,那么现有模型将不再有效,因为它们在迁移时没有密码。
    【解决方案5】:

    我已经在用户密码验证中解决了这个问题,如下所示:

    validates :password, :presence     => true,
                         :confirmation => true,
                         :if           => :password # only validate if password changed!
    

    【讨论】:

    • 哎呀,只是注意到如果这样不管,这将无法解决您的问题,因为您最终可能会在未经验证的情况下更新密码!我在密码中添加了一个 attr_accessible 以使其仅在 :create 和 :update_password 上可用。以防万一您也考虑采用这种方式-或者只是结合我和@mb14的答案
    • " 我在密码中添加了一个 attr_accessible 以使其仅在 :create 和 :update_password 上可用" 你能解释一下如何执行此操作吗?
    • 结合你的答案和 mb14 答案不会输出错误,但不会保存更改。
    • 我的意思不是修改参数,而是创建一个新的,其中包含除密码之外的所有内容。
    • 我不明白,我已经添加了我的用户模型,也许,如果你有时间,检查一下,也许那里有问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多