世界上最伟大的投资就是投资自己的教育

全场限时 5 折

首页Ruby
随风 · 练气

释出自己的 ruby gem 02 acts_as_avatar 给系统自动加上数种随机头像

随风发布于3621 次阅读

上一节:释出自己的 ruby gem 01 where_streets 实现省市县镇四级联动

我们经常要给系统,比如一个后台,添加用户的头像,有时候我想先随机给每个后台用户先生成一个,那么可以用这个 gem。

acts_as_avatar

源码:acts_as_avatar(欢迎 star)

第二个 gem 是关于头像的,先看下效果

这个头像不止一种。

还有其他几种:

这些头像是可以配置的,先用哪种,只要在配置文件里修改下就行。

安装使用

https://rubygems.org/gems/acts_as_avatar

bundle add acts_as_avatar

生成表和配置文件:

rails g acts_as_avatar:install

使用方法很简单:

# view
<%= acts_as_avatar_tag(admin_user, class: "rounded-circle") %>

<%= acts_as_avatar_tag(current_admin_user, size: 36, class: "rounded-circle") %>

<%= acts_as_avatar_tag(current_admin_user, name: :avatar_name, class: "rounded-circle") %>

<%= github_avatar_tag complexity: 5, size: 60 %>

<%= github_avatar_tag size: 60, rounded_circle: true %>

# model
acts_as_avatar inline_svg_engine: :initial_avatar

# or

acts_as_avatar

配置文件的内容如下:

# frozen_string_literal: true

# config/initializers/acts_as_avatar.rb
ActsAsAvatar.configure do |config|
  config.random_image_engine = ENV["random_image_engine"]
  # config.uifaces_limit       = 20
  # config.uifaces_gender      = "female"
  # config.uifaces_uri         = "https://api.uifaces.co"
  # config.uifaces_api_key     = ""
  # config.default_file_name   = "default_avatar"
  # config.upload_max_size     = 2.megabytes
  # config.avatar_size         = 60
  config.inline_svg_engine     = ENV["inline_svg_engine"]
  config.avatar_name           = :avatar_name
  config.class_type            = %w[AdminUser]
  config.github_complexity     = 5
  config.github_render_method  = "square"
  config.github_rounded_circle = true
end

关于配置文件的各种取值,可以看这个文件:

https://github.com/hfpp2012copy/acts_as_avatar/blob/main/lib/acts_as_avatar/generators/templates/initializer.rb.tt

比如 random_image_engine 的取值就是 :letter_avatar, :uifaces_avatar, :github_avatar, or :identicon_avatar

你可以试下,会变成不同的图标。

源码和原理

主要的原理就是在每个使用头像的 model 保存时,把随机头像放进去,放到一个单独的表中。

这个是核心,了解下:

    # belongs_to :avatarable, polymorphic: true
    delegated_type :avatarable, types: ActsAsAvatar.configuration.class_type
    validates :avatarable_type, presence: true
    # delegate :email, to: :avatarable
    # accepts_nested_attributes_for :avatarable
    has_one_attached :upload_avatar
    has_one_attached :default_avatar
    after_create_commit :add_default_avatar, if: -> { random_image_engine.present? }
    validates :upload_avatar, size: { less_than: ActsAsAvatar.configuration.upload_max_size },
                              content_type: %r{\Aimage/.*\z}
    after_create_commit :sanitize_svg, if: :svg?

主要是这个:after_create_commit

表示在创建 model 里会去创建 随机的头像,

这里用到了 default_avatar 和 upload_avatar,

upload_avatar 表示默认的随机头像,这个 gem 还支持自定义用户自己上传头像,用 upload_avatar 来表示。(后面会演示到)

这个表的结果是这样的:

# == Schema Information
#
# Table name: act_as_avatars
#
#  id              :bigint           not null, primary key
#  avatarable_type :string           not null
#  created_at      :datetime         not null
#  updated_at      :datetime         not null
#  avatarable_id   :bigint           not null
#
# Indexes
#
#  index_avatars_on_avatarable  (avatarable_type,avatarable_id)
#

上面是核心的,其他的都是细节,可以通过读源码知道。

https://github.com/hfpp2012copy/acts_as_avatar/blob/main/lib/acts_as_avatar/class_methods.rb model 里有使用的 method 的源码。

可以用的 helper 方法放在这里:

https://github.com/hfpp2012copy/acts_as_avatar/blob/main/lib/acts_as_avatar/helper.rb

可以自行找来用。

其中有个头像是用了第三方的 api ,原理在这里:https://github.com/hfpp2012copy/acts_as_avatar/blob/main/lib/acts_as_avatar/request.rb

值得注意的是,头像也支持 svg ,我用到了 svg 的清理技术,有兴趣的可以了解下:

https://github.com/hfpp2012copy/acts_as_avatar/blob/main/lib/acts_as_avatar/scrubber.rb

有一个头像好像是 github 头像,用到了 js ,我用了 js 去调 ruby。

https://github.com/hfpp2012copy/acts_as_avatar/blob/main/lib/acts_as_avatar/github_avatar.rb

差不多是这样,有问题可以一起讨论交流。

额外补充(仅供参考)

我在表单使用这个 gem 的时候,比如进行头像的上传操作,进行了一点封装,可以简单用一行来搞定

<%= f.avatar_file_field :upload_avatar, remove_path: remove_avatar_admin_users_path %>

效果是这样的:

这里支持自定义上传。

上传完还可以删除掉默认的头像:

我是这样实现的,仅供参考。

跟一节一样,我利用 bootstrap_form 对 avatar_file_field 这个方法进行了封装。

    def avatar_file_field(field_name, remove_path:, **options)
      buttons = content_tag :div do
        concat avatar_create_button
        concat avatar_delete_button(remove_path)
      end

      content_tag(:div, class: "mb-3 row") do
        label(field_name, class: label_col) +
          content_tag(:div, class: "pt-2 #{control_col}") do
            concat avatar_preview_field
            concat buttons
            concat avatar_file_field_without_bootstrap(field_name, **options)
          end
      end
    end

删除 avatar 写了 actions:

    # @route DELETE /admin/users/remove_avatar (remove_avatar_admin_users)
    def remove_avatar
      respond_with @admin_user, flash_now: true do |format|
        @admin_user.upload_avatar.purge

        format.turbo_stream { render :update_account }
      end
    end

    # @route DELETE /admin/users/:id/remove_user_avatar (remove_user_avatar_admin_user)
    def remove_user_avatar
      respond_with @admin_user, flash_now: true do |format|
        @admin_user.upload_avatar.purge

        format.turbo_stream { render :update }
      end
    end

这是删除的。

上传的话就简单,你只要把 upload_avatar 这个参数提交就行。

最后类似这样:

<%= bootstrap_form_with model: admin_user, url: admin_account_path, method: :put, data: { controller: "form--request ts--cities-select dropzone-uploader" }, html: { class: "needs-validation mt-3" } do |form| %>
  <%= form.fields_for :avatar do |f| %>
    <%= f.avatar_file_field :upload_avatar, remove_path: remove_avatar_admin_users_path %>
  <% end %>
  <%= form.update_button %>
<% end %>

就这样。

其他

最近别忘了 follow 和 star(换了一个新的 github 号)

有问题可以一起交流,wechat: qiuzhi99pro

其它的等我慢慢更新。想学 ruby 和 rails 的可以看看我录制的教程哈:https://www.qiuzhi99.com/playlists/ruby.html

原文链接:https://www.qiuzhi99.com/articles/ruby/97611.html

本站文章均为原创内容,如需转载请注明出处,谢谢。

0 条回复
暂无回复~~
喜欢
统计信息
    学员: 29226
    视频数量: 1985
    文章数量: 489

© 汕尾市求知科技有限公司 | Rails365 Gitlab | Qiuzhi99 Gitlab | 知乎 | b 站 | 搜索

粤公网安备 44152102000088号粤公网安备 44152102000088号 | 粤ICP备19038915号

Top