0

please help solve the problem.

models:

class Video < ActiveRecord::Base
  belongs_to :user

  include ActiveModel::Validations

  class FileSizeValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
      record.errors.add attribute, "must start with 'the'" unless 1 == 1 # this is test
    end
  end

  validates :video, file_size: true
end

class User < ActiveRecord::Base
  devise  :database_authenticatable, 
          :registerable,
          :recoverable, 
          :rememberable, 
          :trackable, 
          :validatable
  has_many :videos
end

form:

<%= form_for [current_user, @video] do |f| %>
    <%= f.file_field :video %>
    <%= f.submit %>
<% end %>

video controller:

def create   
  if params[:video][:video]
    filename = params[:video][:video].original_filename 
  else
    filename = nil
  end

  @video = current_user.videos.create(filename: filename)
  if @video.save
    flash[:success] = :saved
    redirect_to user_videos_path(current_user)
  else
    flash.now[:error] = :not_saved
    render 'new'
  end
end

If I send the form with the filled field 'video', then I get the following error message:

Started POST "/users/48/videos" for 127.0.0.1 at 2015-07-20 17:33:46 +0300
Processing by VideosController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"ukh4iiMQEimDvbOpEtdwTBNeYpdgKZDzepyhnNTWCVRRNx2Xu9v95Wl1iRFp8VDGuDid/BY8ioyedtGbM/imJQ==", "video"=>{"video"=>#<ActionDispatch::Http::UploadedFile:0x007fc278691760 @tempfile=#<Tempfile:/tmp/RackMultipart20150720-25326-1wrjooo.jpg>, @original_filename="im2.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"video[video]\"; filename=\"im2.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Create Video", "user_id"=>"48"}
  User Load (0.7ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 48]]
   (0.2ms)  BEGIN
   (0.2ms)  ROLLBACK
Completed 500 Internal Server Error in 32ms (ActiveRecord: 1.2ms)

NoMethodError (undefined method `video' for #<Video:0x007fc279389828>):
  app/controllers/videos_controller.rb:25:in `create'

If I send the form with the empty field 'video', then I get the following error message:

Started POST "/users/48/videos" for 127.0.0.1 at 2015-07-20 17:38:31 +0300
Processing by VideosController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"kLKGzKQiu6QSFC85EQf0xT5bw0LZcHFxlDb6bcsPlTR7zePRPOlUaPjcFYFqIdRPlT08Ka9law5w3IpqLCE6RQ==", "commit"=>"Create Video", "user_id"=>"48"}
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms)

NoMethodError (undefined method `[]' for nil:NilClass):
  app/controllers/videos_controller.rb:19:in `create'

please help write a validator 'file_size'. I used the documentation: http://api.rubyonrails.org/classes/ActiveModel/Validator.html

2 Answers 2

1

Actually you can do something very simple if you just want to run a method

class Video < ActiveRecord::Base

  # Notice that it's **validate** without the ending **s**
  validate :video_file_size

  # Notice that it doesn't matter what you return, video will stay valid unless you add an error to the `errors` array
  def video_file_size
    if file_size > 10.megabytes
      errors.add :video_file_size, "Video file size must be less than 10 megabytes"
    end
  end

end

This should be enough, without the additional validator class, which is reasonable only if you intend to use it in multiple models.

Sign up to request clarification or add additional context in comments.

4 Comments

please tell me how do I pass the uploaded file size to video_file_size()
Well, you can find it in params! If your file field is named myfile, you'll find it as params[:myfile].size. Migrate your Video model adding a column file_size and ensure you pass in file size when building the object. Simple and effective
params unfortunately not available in the model: NameError (undefined local variable or method `params' for #<Video:0x007f2054f1f718>):
You must pass params when building your Video object from the controller, params not available on model, of course.
0

You can't use validates <field>, ... if field doesn't exist on your model. If you want to load a validator that runs against the entire model and not a specific field, you need

class Video < ActiveRecord::Base

  validates_with FileSizeValidator

end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.