0

I am trying to use predefined constant in Model virtual attributes.

when I create user, it shows absolute avatar_url and works fine.

Problem:

when I find user in login method it return only relative url i.e "avatar_url": "/avatars/original/missing.png" which means #{SERVER_BASE_PATH} is not interpolating at that moment.

It also works fine with some api call i.e when updating user. but not in all cases. please help me how can I fix this problem in order to get absolute url in all api calls

Example:

Model:

class User < ApplicationRecord
    # user model
    # if avatar url is empty then use default image url
    # SERVER_BASE_PATH is defined in config/initializer/constant.rb
    attribute :avatar_url, :string, default: -> { "#{SERVER_BASE_PATH}/avatars/original/missing.png" }
end

Controller:

it has simple login method

class UsersController < ApplicationController
    def login
        response = OK()
        unless params[:email].present? and params[:password].present?
            render json: missing_params_specific('either user [email] or [password]') and return
        end
        response[:user] = []
        response[:status] = '0'

        begin
        user = User.find_by(email: params[:email].downcase)
        if user && user.authenticate(params[:password])
            # following line first check if user profile image exist then it places that image url given by paperclip
            # if not exist then url defined in model virtual attributes is used.
            user.avatar_url = user.avatar.url if user.avatar.url.present?
            user.set_last_sign_in_at user.sign_in_count
          response[:user] = user
          response[:status] = '1'
        else
          response[:message] = 'Invalid email/password combination' # Not quite right!
        end
        rescue => e
            response[:message] = e.message
        end
        render json: response and return
    end
end

API JSON Response:

{
  "JSON_KEY_STATUS_CODE": 1,
  "JSON_KEY_STATUS_MESSAGE": "OK",
  "server_time": 1490623384,
  "user": {
    "confirmed": true,
    "user_status": "Active",
    "admin": false,
    "user_role": "Standard",
    "first_name": "Super",
    "last_name": "User",
    "full_name": "Super User",
    "avatar_url": "/avatars/original/missing.png",  <-- Here (not absolute url)
    "is_active": true,
  },
  "status": "1"
}
Kaleem Ullah
  • 6,799
  • 3
  • 42
  • 47
  • Why not just use the [rails asset helpers](http://api.rubyonrails.org/classes/ActionView/Helpers/AssetUrlHelper.html#method-i-path_to_asset) to give you a path to an asset in `/public` instead of using a constant? – max Mar 27 '17 at 14:49
  • I am using rails api. it has no assets pipeline AFAIK. – Kaleem Ullah Mar 27 '17 at 14:52

1 Answers1

1

From what I understand, the "avatar_url" attribute on your JSON response is the default_url that you define on your model that you integrate Paperclip with:

class User < ActiveRecord::Base
  has_attached_file :avatar, 
                    styles: { medium: "300x300>", thumb: "100x100>" },
                    default_url: "/images/:style/missing.png"
  validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\z/
end

Did you try to set the default_url with you SERVER_BASE_PATH?

Holger Frohloff
  • 1,695
  • 18
  • 29
  • yes, it works. thank you for helping. one thing I want to know. that `avatar_url` is being overridden by `default_url`. cause path set in `default_url` is reflected in `avatar_url`. and I don't know why – Kaleem Ullah Mar 27 '17 at 15:16
  • This is as how Paperclip works. Perhaps I don't understand your question correctly. Have a look at these urls: https://github.com/thoughtbot/paperclip/blob/7edb35a2a9a80c9598dfde235c7e593c023fc914/lib/paperclip/attachment.rb#L144 and https://github.com/thoughtbot/paperclip/blob/ce9197268125770db427f252f9c5a2e729311305/lib/paperclip.rb#L183 Perhaps they are of help. You can specify methods on your model to overwrite the `default_url` values. – Holger Frohloff Mar 27 '17 at 15:21