百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
A

active_type

> 编程语言
开源

让任何 Ruby 对象都像 ActiveRecord 一样发出鸣叫

1.1K stars0 点赞0 次浏览
访问官网GitHub

工具介绍

让任何 Ruby 对象都像 ActiveRecord 一样发出鸣叫

Make any Ruby object quack like ActiveRecord

ActiveType is our take on "presenter models" (or "form models") in Rails. We want to have controllers (and forms) talk to models that are either not backed by a database table, or have additional functionality that should not be shared to the rest of the application.

However, we do not want to lose ActiveRecord's amenities, like validations, callbacks, etc.

Examples for use cases are models to support sign in:

ruby
class SignIn  "User (...)"

# or
sign_up = SignUp.new
sign_up.class # => "SignUp (...)"
sign_up.class.extended_record_base_class # => "User (...)"

Inheriting from ActiveType:: objects

If you want to inherit from an ActiveType class, simply do

ruby
class SignUp  "kratob").nickname # "kratob"

Overriding accessors

You can override attribute getters and setters using super:

ruby
class SignIn 
  

    
      

    
  
  • You have to say nests_many :records

  • records will be validated and saved automatically

  • The generated .records_attributes = expects parameters like ActiveRecord's nested attributes, and works together with the fields_for helper:

    • either as a hash (where the keys are meaningless)

      ruby
      {
        '1' => { date: "new record's date" },
        '2' => { id: '3', date: "existing record's date" }
      }
    • or as an array

      ruby
      [
        { date: "new record's date" },
        { id: '3', date: "existing record's date" }
      ]

To use it with single records, use nests_one. It works like accept_nested_attributes does for has_one. Use .record_attributes = to build the child record.

Supported options for nests_many / nests_one are:

  • build_scope

    Used to build new records, for example:

    ruby
    nests_many :documents, build_scope: proc { Document.where(:state => "fresh") }
  • find_scope

    Used to find existing records (in order to update them).

  • scope

    Sets find_scope and build_scope together.

    If you don't supply a scope, ActiveType will guess from the association name, i.e. saying

    ruby
    nests_many :documents

    is the same as saying

    ruby
    nests_many :documents, scope: proc { Document }

    which is identical to

    ruby
    nests_many :documents, build_scope: proc { Document }, find_scope: proc { Document }

    All ...scope options are evaled in the context of the record on first use, and cached.

  • allow_destroy

    Allow to destroy records if the attributes contain _destroy => '1'

  • reject_if

    Pass either a proc of the form proc { |attributes| ... }, or a symbol indicating a method, or :all_blank.

    Will reject attributes for which the proc or the method returns true, or with only blank values (for :all_blank).

  • default

    Initializes the association on first access with the given proc:

    ruby
    nests_many :documents, default: proc { Documents.all }

Options supported exclusively by nests_many are:

  • index_errors

    Use a boolean to get indexed errors on related records. In Rails 5 you can make it global with config.active_record.index_nested_attribute_errors = true.

Casting records or relations

When working with ActiveType you will often find it useful to cast an ActiveRecord instance to its extended ActiveType::Record variant.

Use ActiveType.cast for this:

ruby
class User  true

This is basically like ActiveRecord#becomes, but with less bugs and more consistent behavior.

Note that cast is destructive. The originally casted record (user) and the returned record (sign_up) share internal state (such as attributes). To avoid unexpected behavior, the original record will raise an error when trying to change or persist it. Also, casting of a record that has changes in its loaded associations is prevented, because those changes would be lost. If you know what you are doing and absolutely want that, you may use the option force: true to allow this potentially problematic behaviour, e.g. sign_up = ActiveType.cast(user, SignUp, force: true)

You can also cast an entire relation (scope) to a relation of an ActiveType::Record:

ruby
adult_users = User.where('age >= 18')
adult_sign_ups = ActiveType.cast(adult_users, SignUp)
sign_up = adult_sign_ups.find(1)
sign_up.is_a?(SignUp) # => true

If you need to add some special logic after casting you can add an after_cast method:

ruby
class SignUp  bundle exec rspec spec`.
- When you make a pull request, tests are automatically run against all variants and Rubies on travis.ci.

If you would like to contribute:

- Fork the repository.
- Push your changes **with passing specs**.
- Send us a pull request.

I'm very eager to keep this gem lightweight and on topic. If you're unsure whether a change would make it into the gem, [talk to me beforehand](mailto:[email protected]).

Credits
-------

Tobias Kraze from [makandra](http://makandra.com/)

Henning Koch from [makandra](http://makandra.com/)

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

Ruby

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言