{"id":16102350,"url":"https://github.com/sshaw/column_namespace","last_synced_at":"2025-04-06T01:11:45.285Z","repository":{"id":62556035,"uuid":"264324861","full_name":"sshaw/column_namespace","owner":"sshaw","description":"Group columns on your Active Record model under a \"namespace method\"","archived":false,"fork":false,"pushed_at":"2020-05-23T04:48:52.000Z","size":7,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-12T10:49:28.274Z","etag":null,"topics":["activerecord","columns","rails","ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sshaw.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-16T00:06:25.000Z","updated_at":"2020-05-23T02:59:10.000Z","dependencies_parsed_at":"2022-11-03T06:00:26.188Z","dependency_job_id":null,"html_url":"https://github.com/sshaw/column_namespace","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaw%2Fcolumn_namespace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaw%2Fcolumn_namespace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaw%2Fcolumn_namespace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshaw%2Fcolumn_namespace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sshaw","download_url":"https://codeload.github.com/sshaw/column_namespace/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247419871,"owners_count":20936013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["activerecord","columns","rails","ruby"],"created_at":"2024-10-09T18:53:36.599Z","updated_at":"2025-04-06T01:11:45.263Z","avatar_url":"https://github.com/sshaw.png","language":"Ruby","readme":"# Column Namespace\n\n[![Build Status](https://travis-ci.org/sshaw/column_namespace.svg?branch=master)](https://travis-ci.org/sshaw/column_namespace)\n\nGroup columns on your Active Record model under a \"namespace method\".\n\n## Usage\n\nGiven the following database table (note the columns beginning with `\"external_\"`):\n```sql\ncreate table products (\n  id int unsigned,\n  name varchar(255),\n  external_product_id bigint unsigned,\n  external_variant_id bigint unsigned,\n  external_metafield_id bigint unsigned\n)\n```\n\nAdd the following to its model:\n```ruby\nclass Product \u003c ApplicationRecord\n  extend ColumnNamespace\n  column_namespace \"external_\"\nend\n```\n\nNow you can do:\n```ruby\nproduct = Product.new(:external =\u003e { :product_id =\u003e 123, :variant_id =\u003e 999 })\n\np product.external.product_id  # 123\np product.external.variant_id  # 999\n\nproduct.save!\n\np product[:external_variant_id]  # 999\n\nproduct.external.variant_id = 21341510\nproduct.save!\n\nproduct[:external_variant_id]  # 21341510\n\nproduct = Product.last\np product.external.to_h  # { :product_id =\u003e 1, :metafield_id =\u003e nil, ... }\n```\n\nAlternatively you can specify the namespace method and its columns:\n```ruby\nclass Product \u003c ApplicationRecord\n  extend ColumnNamespace\n  column_namespace :some_method =\u003e %w[name external_product_id]\nend\n```\n\nThis gives you:\n```ruby\nproduct = Product.new(:some_method =\u003e { :name =\u003e \"sshaw\", :external_product_id =\u003e 99 })\nproduct.some_method.name = nil\nproduct.some_method.external_product_id = 1_000_00\n\n# etc... same stuff as before\n```\n\n\n### But Isn't This What `composed_of` Does‽\n\nYes, but, no!\n\n`composed_of` forces you to create and explicitly use a \"value object\". In some cases (like in the above examples)\nthis class is artificial. It doesn't exist in your domain –nor should it!\n\nUsing the above examples with `composed_of` do not work. Instead of:\n```ruby\nproduct = Product.last\nproduct.external.product_id = 510\nproduct.save!  # does not save 510\n```\n\nYou'd have to write:\n```ruby\nproduct = Product.last\nproduct.external = External.new(:product_id =\u003e 510)\nproduct.save!\n```\n\nThe same applies for validation:\n```ruby\n# In Product:\n# validates :external_product_id, :numericality =\u003e { :greater_than =\u003e -1 }\nproduct = Product.last\nproduct.external.product_id = -1\nproduct.valid?  # true\n```\n\nYou'd have to assign an instance of `External` to `product.external` for this to work.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem \"column_namespace\"\n```\n\nOr:\n\n```\ngem install column_namespace\n```\n\n## Author\n\nSkye Shaw [skye.shaw AT gmail.com]\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshaw%2Fcolumn_namespace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsshaw%2Fcolumn_namespace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshaw%2Fcolumn_namespace/lists"}