Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/igorkasyanchuk/mechanical
All models in a single table, new attributes without migrations. Works like regular AR model
https://github.com/igorkasyanchuk/mechanical
Last synced: about 2 months ago
JSON representation
All models in a single table, new attributes without migrations. Works like regular AR model
- Host: GitHub
- URL: https://github.com/igorkasyanchuk/mechanical
- Owner: igorkasyanchuk
- License: mit
- Created: 2019-09-12T20:16:21.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2022-05-21T17:50:16.000Z (over 2 years ago)
- Last Synced: 2024-04-14T07:00:45.814Z (6 months ago)
- Language: Ruby
- Homepage: https://www.railsjazz.com/
- Size: 62.5 KB
- Stars: 17
- Watchers: 3
- Forks: 0
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: MIT-LICENSE
Awesome Lists containing this project
README
# Mechanical
[![RailsJazz](https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/my_other.svg?raw=true)](https://www.railsjazz.com)
[![https://www.patreon.com/igorkasyanchuk](https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/patron.svg?raw=true)](https://www.patreon.com/igorkasyanchuk)Simple gem which allows to store multiple models in a single table in DB (Postgres only). It's using STI and Postgres JSONB data type.
The whole schema is defined in one initializer file, and new attributes could be easily added just by adding new attribute in that file. So you don't need to create a migration.
## Usage
- add in the Gemfile `gem "mechanical"`
- execute `bundle install`
- execute `rails g mechanical initializer`
- execute `rake db:migrate`
- edit `config/initializers/mechanical.rb` and define your schema
- start app `rails s`
- you can use models `Mechanical::Model::MODEL_NAME` in you app like a regular model.You need to define attribute and it's type (it's importan to check this gem: https://github.com/madeintandem/jsonb_accessor).
In addition you can specify relations, validations, add instance or class methods. Behavior is the same as with AR model.```ruby
Mechanical.setup do |config|
model "Account" do
field :name, type: :string
field :balance, type: :integerhas_many :posts
validates :name, presence: true
validates :balance, numericality: true
endmodel "Post" do
field :title, type: :string
field :description, type: :text
field :published_on, type: :date
field :account_id, type: :integer
field :active, type: :boolean, default: truebelongs_to :account, optional: true
has_one_attached :file
validates :title, presence: true
scope :active, -> { jsonb_where(:mechanical_data, active: true) }
after_create :say_hello
add_methods do
def self.total_posts
self.count
enddef title_uppercase
title&.upcase
enddef say_hello
puts "HELLO FROM initializer #{self}"
end
end
endend
```After Installation you can do the following:
```ruby
post = Mechanical::Model::Post.create(title: "Hello world", description: "this is description")
post.persisted? # truepost.title # "Hello world"
post.description # "this is description"# for querying use: https://github.com/madeintandem/jsonb_accessor
Mechanical::Model::Post.create(title: "ABC", description: "this is description")
Mechanical::Model::Post.create(title: "TRE", description: "this is second description")
Mechanical::Model::Account.create(name: "XYZ", balance: 100)
Mechanical::Model::Account.create(name: "MTR", balance: 200)
Mechanical::Model::Post.jsonb_where(:mechanical_data, { title: 'ABC' }).count # 1
Mechanical::Model::Account.mechanical_data_where(balance: { greater_than_or_equal_to: 150 }).count # 1
Mechanical::Model::Account.mechanical_data_where(balance: 10..250).count # 2
```If you are building form and want to use this model you can do it same way as using regular model:
Example of very simple controller:
```ruby
def index
@post = Mechanical::Model::Post.new
enddef submit_post
@post = Mechanical::Model::Post.new(params.require(:post).permit!)
@post.user = User.first
@post.save
if @post.save
redirect_to root_path
else
@posts = Mechanical::Model::Post.all
render :index
end
end
```View:
```erb
<%= simple_form_for @post, url: submit_post_url, html: { novalidate: true } do |f| %>
<%= f.error_messages %>
<%= f.association :account %>
<%= f.input :title %>
<%= f.input :description %>
<%= f.input :published_on %>
<%= f.input :file %>
<%= f.input :active %>
<%= f.submit %>
<% end %>```
As you can see it supports active storage.
## Installation
Add this line to your application's Gemfile:```ruby
gem 'mechanical'
```And then execute:
```bash
$ bundle
```
## ContributingYou are welcome to contribute.
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
[](https://www.railsjazz.com/?utm_source=github&utm_medium=bottom&utm_campaign=mechanical)