{"action":"created","issue":{"url":"https://api.github.com/repos/thoughtbot/paperclip/issues/1843","labels_url":"https://api.github.com/repos/thoughtbot/paperclip/issues/1843/labels{/name}","comments_url":"https://api.github.com/repos/thoughtbot/paperclip/issues/1843/comments","events_url":"https://api.github.com/repos/thoughtbot/paperclip/issues/1843/events","html_url":"https://github.com/thoughtbot/paperclip/issues/1843","id":72386417,"number":1843,"title":"InfiniteInterpolation error on model.file.url if file.exists? is false","user":{"login":"vedant1811","id":3260363,"avatar_url":"https://avatars.githubusercontent.com/u/3260363?v=3","gravatar_id":"","url":"https://api.github.com/users/vedant1811","html_url":"https://github.com/vedant1811","followers_url":"https://api.github.com/users/vedant1811/followers","following_url":"https://api.github.com/users/vedant1811/following{/other_user}","gists_url":"https://api.github.com/users/vedant1811/gists{/gist_id}","starred_url":"https://api.github.com/users/vedant1811/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vedant1811/subscriptions","organizations_url":"https://api.github.com/users/vedant1811/orgs","repos_url":"https://api.github.com/users/vedant1811/repos","events_url":"https://api.github.com/users/vedant1811/events{/privacy}","received_events_url":"https://api.github.com/users/vedant1811/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/thoughtbot/paperclip/labels/Cannot%20Reproduce","name":"Cannot Reproduce","color":"d4c5f9"},{"url":"https://api.github.com/repos/thoughtbot/paperclip/labels/More%20info%20needed","name":"More info needed","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-05-01T08:44:27Z","updated_at":"2015-06-02T11:09:12Z","closed_at":null,"body":"Paperclip seems to be throwing errors where it should be returning `nil`, or atleast, failing with an improper error message.\r\n\r\nIf a model that `has_attachment :file` returns `false` for `model.file.exists?`, it throws a `Paperclip::Errors::InfiniteInterpolationError` in `model.file.url`\r\n\r\nIn rails console:\r\n\r\n    irb(main):013:0* seller.image.exists?\r\n    => false\r\nthen\r\n\r\n    irb(main):011:0> seller.image.url\r\n    Paperclip::Errors::InfiniteInterpolationError: Paperclip::Errors::InfiniteInterpolationError\r\n    from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:53:in `url'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:34:in `block (2 levels) in interpolate'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `gsub'\r\n    from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `block in interpolate'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `each'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `inject'\r\n    from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `interpolate'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/url_generator.rb:13:in `for'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:143:in `url'\r\n    from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:54:in `url'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:34:in `block (2 levels) in interpolate'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `gsub'\r\n    from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:33:in `block in interpolate'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `each'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `inject'\r\n    from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/interpolations.rb:32:in `interpolate'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/url_generator.rb:13:in `for'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/paperclip-4.2.1/lib/paperclip/attachment.rb:143:in `url'\r\n    from (irb):11\r\n    from /home/vedant/.gem/ruby/2.2.1/gems/railties-4.2.1/lib/rails/commands/console.rb:110:in `start'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/railties-4.2.1/lib/rails/commands/console.rb:9:in `start'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:68:in `console'\r\n    from /home/vedant/.gem/ruby/2.2.1/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:39:in `run_command!'\r\n            from /home/vedant/.gem/ruby/2.2.1/gems/railties-4.2.1/lib/rails/commands.rb:17:in `<top (required)>'\r\n            from bin/rails:4:in `require'\r\n    from bin/rails:4:in `<main>'irb(main):012:0>"},"comment":{"url":"https://api.github.com/repos/thoughtbot/paperclip/issues/comments/107917334","html_url":"https://github.com/thoughtbot/paperclip/issues/1843#issuecomment-107917334","issue_url":"https://api.github.com/repos/thoughtbot/paperclip/issues/1843","id":107917334,"user":{"login":"vedant1811","id":3260363,"avatar_url":"https://avatars.githubusercontent.com/u/3260363?v=3","gravatar_id":"","url":"https://api.github.com/users/vedant1811","html_url":"https://github.com/vedant1811","followers_url":"https://api.github.com/users/vedant1811/followers","following_url":"https://api.github.com/users/vedant1811/following{/other_user}","gists_url":"https://api.github.com/users/vedant1811/gists{/gist_id}","starred_url":"https://api.github.com/users/vedant1811/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vedant1811/subscriptions","organizations_url":"https://api.github.com/users/vedant1811/orgs","repos_url":"https://api.github.com/users/vedant1811/repos","events_url":"https://api.github.com/users/vedant1811/events{/privacy}","received_events_url":"https://api.github.com/users/vedant1811/received_events","type":"User","site_admin":false},"created_at":"2015-06-02T11:09:12Z","updated_at":"2015-06-02T11:09:12Z","body":"Here's my full model definition. I have modified the`url` as you can see.\r\n\r\n    class V1::Seller < ActiveRecord::Base\r\n      before_create :generate_api_key, :sanitize_file_name\r\n      after_create :send_welcome_email\r\n      after_save :notify\r\n\r\n      has_attached_file :image, # paperclip options:\r\n                        :preserve_files => \"false\",\r\n                        :styles => {:card => '427x240>'},\r\n                        :url => \"/:rails_env/#{table_name}/images/:style/:filename\",\r\n                        :default_url => \":url/missing.png\",\r\n                        :path => \":url\",\r\n                        :storage => :s3,\r\n                        :s3_headers => { 'Expires' => 1.year.from_now.httpdate },\r\n                        :s3_credentials => \"#{Rails.root}/config/secrets.yml\",\r\n                        :bucket => 'instano',\r\n                        :s3_storage_class => :reduced_redundancy\r\n    \r\n      has_many :deals, :class_name => 'V1::Deal', dependent: :destroy\r\n      has_many :quotations, :class_name => 'V1::Quotation', dependent: :destroy\r\n      has_many :brands, :class_name => 'V1::Brand', dependent: :destroy\r\n      has_many :brand_names, :class_name => 'V1::BrandName', through: :brands\r\n      has_many :category_names, :class_name => 'V1::CategoryName', through: :brand_names\r\n      has_many :devices, :class_name => 'V1::Device', dependent: :nullify\r\n      has_many :outlets, :class_name => 'V1::Outlet'\r\n\r\n      accepts_nested_attributes_for :brands\r\n\r\n      validates :rating, presence: true\r\n      validates :email, presence: true, uniqueness: true\r\n\r\n      # paperclip:\r\n      validates_with AttachmentFileNameValidator, :attributes => :image, :matches => [/png\\Z/, /jpe?g\\Z/]\r\n      validates_with AttachmentContentTypeValidator, :attributes => :image, :content_type => /\\Aimage\\/.*\\Z/\r\n      validates_with AttachmentSizeValidator, :attributes => :image, :less_than => 2.megabytes\r\n\r\n      # important! do NOT reorder entries\r\n      enum status: [\r\n        # invisible in app\r\n        :removed,\r\n        :inactive,\r\n        # visible in app\r\n        :unverified,\r\n        :verified,\r\n        :deal_provider\r\n      ]\r\n\r\n      scope :visible, -> { where('status >= ?', V1::Seller.statuses[:unverified]) }\r\n\r\n      has_secure_password\r\n      has_paper_trail\r\n\r\n      def title\r\n        \"#{name_of_shop} (#{id})\"\r\n      end\r\n\r\n      rails_admin do\r\n        configure :status do\r\n          searchable false\r\n        end\r\n        clone_config do\r\n          custom_method :shallow_clone\r\n        end\r\n        list do\r\n          field :name_of_shop\r\n          field :image\r\n          field :description\r\n          field :brand_names\r\n          field :status, :enum\r\n          field :phone\r\n          field :email\r\n          sort_by :created_at\r\n          items_per_page 100\r\n        end\r\n        show do\r\n          field :id\r\n          field :status, :enum\r\n          field :name_of_shop\r\n          field :image\r\n          field :description\r\n          field :outlets\r\n          field :brand_names\r\n          field :phone\r\n          field :email\r\n          field :created_at\r\n          field :updated_at\r\n        end\r\n        edit do # both edit and create\r\n          field :name_of_shop\r\n          field :image\r\n          field :description, :ck_editor\r\n          field :status\r\n          field :email\r\n          # TODO: fix: (also see: https://github.com/sferik/rails_admin/issues/2150)\r\n          field :password\r\n          field :password_confirmation\r\n          field :phone\r\n          field :brands\r\n          field :brand_names do\r\n            label \"edit brands\"\r\n            help \"Use only to edit brands. Do not add/remove categories\"\r\n          end\r\n        end\r\n      end\r\n\r\n      def self.authenticate(email, password)\r\n        seller = find_by_email(email)\r\n        if seller && seller.authenticate(password)\r\n          seller\r\n        else\r\n          nil\r\n        end\r\n      end\r\n\r\n      def assign_categories(params)\r\n        begin\r\n          puts 'starting assign_categories'\r\n          puts params.inspect\r\n          permitted = params.require(:seller).permit(brands: [:name, :category])\r\n          puts permitted.inspect\r\n\r\n          self.brands.clear\r\n\r\n          permitted[:brands].each do |c|\r\n            next if c[:name].nil? || c[:category].nil?\r\n\r\n            category_name = V1::CategoryName.find_by(name: c[:category])\r\n            if category_name\r\n              brand_name = V1::BrandName.find_by(name: c[:name], category_name: category_name)\r\n              self.brand_names << brand_name if brand_name\r\n            end\r\n          end\r\n        rescue ActionController::ParameterMissing => e\r\n          logger.error e\r\n        end\r\n      end\r\n\r\n    private\r\n      def sanitize_file_name\r\n        if image_file_name\r\n          extension = File.extname(image_file_name).downcase\r\n          self.image.instance_write(:file_name, \"#{self.name.parameterize('_')}#{extension}\")\r\n        end\r\n      end\r\n\r\n      def shallow_clone\r\n        self.dup.tap do |seller|\r\n          seller.password = Rails.application.secrets.placeholder_password\r\n          seller.password_confirmation = seller.password\r\n          seller.email = \"#{self.email}2\"\r\n        end\r\n      end\r\n\r\n      # TODO: notify (and handle the case) if status is changed from visible to invisible in app\r\n      def notify\r\n        return unless verified? || unverified? || deal_provider?\r\n        require 'modules/gcm_notifier'\r\n        GcmNotifier.seller_updated(self)\r\n      end\r\n\r\n      def send_welcome_email\r\n        InstanoMailer.welcome_email(self).deliver_later if verified?\r\n      end\r\n\r\n      def generate_api_key\r\n        begin\r\n          self.api_key = SecureRandom.hex\r\n        end while self.class.exists?(api_key: api_key)\r\n      end\r\n    end\r\n"}}