{"id":18513348,"url":"https://github.com/jbox-web/draper","last_synced_at":"2025-06-23T04:37:46.920Z","repository":{"id":146101202,"uuid":"394370079","full_name":"jbox-web/draper","owner":"jbox-web","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-04T21:02:47.000Z","size":90,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-14T12:19:43.513Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jbox-web.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-08-09T16:48:41.000Z","updated_at":"2025-03-04T21:02:50.000Z","dependencies_parsed_at":"2023-12-15T02:05:02.881Z","dependency_job_id":"bc4c1f5f-edce-42d7-9c58-e04a1dd7de69","html_url":"https://github.com/jbox-web/draper","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbox-web%2Fdraper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbox-web%2Fdraper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbox-web%2Fdraper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbox-web%2Fdraper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jbox-web","download_url":"https://codeload.github.com/jbox-web/draper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254140805,"owners_count":22021225,"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":[],"created_at":"2024-11-06T15:37:46.715Z","updated_at":"2025-05-14T12:20:30.548Z","avatar_url":"https://github.com/jbox-web.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Draper\n\n[![GitHub license](https://img.shields.io/github/license/jbox-web/draper.svg)](https://github.com/jbox-web/draper/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/jbox-web/draper.svg)](https://github.com/jbox-web/draper/releases/latest)\n[![CI](https://github.com/jbox-web/draper/workflows/CI/badge.svg)](https://github.com/jbox-web/draper/actions)\n[![Code Climate](https://codeclimate.com/github/jbox-web/draper/badges/gpa.svg)](https://codeclimate.com/github/jbox-web/draper)\n[![Test Coverage](https://codeclimate.com/github/jbox-web/draper/badges/coverage.svg)](https://codeclimate.com/github/jbox-web/draper/coverage)\n\nDraper adds an object-oriented layer of presentation logic to your Rails\napplication.\n\nWithout Draper, this functionality might have been tangled up in procedural\nhelpers or adding bulk to your models. With Draper decorators, you can wrap your\nmodels with presentation-related logic to organise - and test - this layer of\nyour app much more effectively.\n\n## Installation\n\nPut this in your `Gemfile` :\n\n```ruby\ngit_source(:github){ |repo_name| \"https://github.com/#{repo_name}.git\" }\n\ngem 'draper', github: 'jbox-web/draper', tag: '1.0.0'\n```\n\nthen run `bundle install`.\n\n## Writing Decorators\n\nDecorators inherit from `Draper::Decorator`, live in your `app/decorators`\ndirectory, and are named for the model that they decorate:\n\n```ruby\n# app/decorators/article_decorator.rb\nclass ArticleDecorator \u003c Draper::Decorator\n# ...\nend\n```\n\n### Accessing Helpers\n\nNormal Rails helpers are still useful for lots of tasks. Both Rails' provided\nhelpers and those defined in your app can be accessed within a decorator via the `h` method:\n\n```ruby\nclass ArticleDecorator \u003c Draper::Decorator\n  def emphatic\n    h.content_tag(:strong, \"Awesome\")\n  end\nend\n```\n\n### Accessing the model\n\nWhen writing decorator methods you'll usually need to access the wrapped model.\nWhile you may choose to use delegation ([covered below](#delegating-methods))\nfor convenience, you can always use the `object` (or its alias `model`):\n\n```ruby\nclass ArticleDecorator \u003c Draper::Decorator\n  def published_at\n    object.published_at.strftime(\"%A, %B %e\")\n  end\nend\n```\n\n### Decorating Associated Objects\n\nYou can automatically decorate associated models when the primary model is\ndecorated. Assuming an `Article` model has an associated `Author` object:\n\n```ruby\nclass ArticleDecorator \u003c Draper::Decorator\n  decorates_association :author\nend\n```\n\nWhen `ArticleDecorator` decorates an `Article`, it will also use\n`AuthorDecorator` to decorate the associated `Author`.\n\n### Delegating Methods\n\nWhen your decorator calls `delegate_all`, any method called on the decorator not\ndefined in the decorator itself will be delegated to the decorated object. This\nincludes calling `super` from within the decorator. A call to `super` from within\nthe decorator will first try to call the method on the parent decorator class. If\nthe method does not exist on the parent decorator class, it will then try to call\nthe method on the decorated `object`. This is a very permissive interface.\n\nIf you want to strictly control which methods are called within views, you can\nchoose to only delegate certain methods from the decorator to the source model:\n\n```ruby\nclass ArticleDecorator \u003c Draper::Decorator\n  delegate :title, :body\nend\n```\n\nWe omit the `:to` argument here as it defaults to the `object` being decorated.\nYou could choose to delegate methods to other places like this:\n\n```ruby\nclass ArticleDecorator \u003c Draper::Decorator\n  delegate :title, :body\n  delegate :name, :title, to: :author, prefix: true\nend\n```\n\nFrom your view template, assuming `@article` is decorated, you could do any of\nthe following:\n\n```ruby\n@article.title # Returns the article's `.title`\n@article.body  # Returns the article's `.body`\n@article.author_name  # Returns the article's `author.name`\n@article.author_title # Returns the article's `author.title`\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjbox-web%2Fdraper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjbox-web%2Fdraper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjbox-web%2Fdraper/lists"}