Check and update individual attribute rails

My user model has the following:

attr_accessible :avatar, :email

validates_presence_of :email
has_attached_file :avatar # paperclip

validates_attachment_size :avatar,
                          :less_than => 1.megabyte,
                          :message => 'Image cannot be larger than 1MB in size',
                          :if => Proc.new { |imports| !imports.avatar_file_name.blank? }

in one of my controllers I ONLY want to update and check the status of the avatar without updating and checking email.

How can i do this?

for example (this will not work)

if @user.update_attributes(params[:user])
 # do something... 
end

I also tried with update_attribute('avatar', params[:user][:avatar]), but that would also miss the checks for the avatar field.

+5
source share
5 answers

You can verify the attribute manually and use update_attributethat skips validation . If you add to yourUser :

def self.valid_attribute?(attr, value)
  mock = self.new(attr => value)
  if mock.valid?
    true
  else
    !mock.errors.has_key?(attr)
  end
end

And then update the attribute like this:

if(!User.valid_attribute?('avatar', params[:user][:avatar])
    # Complain or whatever.
end
@user.update_attribute('avatar', params[:user][:avatar])

, (), .

, Milan Novota valid_attribute?, , , , attr ; , - , valid_attribute? .

, :

def update_just_this_one(attr, value)
    raise "Bad #{attr}" if(!User.valid_attribute?(attr, value))
    self.update_attribute(attr, value)
end

.

+13

?

validates_presence_of :email, :if => :email_changed?
+6

validates_presence_of :email?

http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M000083

:

if - , proc , , (: if = > : allow_validation : if = > Proc.new {| user | user.signup_step > 2}). , proc string true false.

except - , proc , , (: if = > : skip_validation, : if = > Proc.new {| user | user.signup_step <= 2 }). , proc string true false.

+1

, , , , .

, , , . , . , , , (, update_attribute).

:

  • , , , , . , , .
  • . , , ? .

, - :

validate :presence_of_email_after_upload_avatar

def presence_of_email_after_upload_avatar
  # write some test, when the email should be present
  if avatar.present?
    errors.add(:email, "Email is required") unless email.present?
  end
end

, .

+1
source

Here is my solution. Does it retain the same behavior as the .valid method ? , witch returns true or false and adds errors to the model on the fact that it was called.

class MyModel < ActiveRecord::Base
  def valid_attributes?(attributes)
    mock = self.class.new(self.attributes)
    mock.valid?
    mock.errors.to_hash.select { |attribute| attributes.include? attribute }.each do |error_key, error_messages|
      error_messages.each do |error_message|
        self.errors.add(error_key, error_message)
      end
    end

    self.errors.to_hash.empty?
  end
end

> my_model.valid_attributes? [:first_name, :email] # => returns true if first_name and email is valid, returns false if at least one is not valid
> my_modal.errors.messages # => now contain errors of the previous validation
{'first_name' => ["can't be blank"]}
+1
source

All Articles