### Install Blueprinter Gem Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Add the Blueprinter gem to your application's Gemfile and run bundle install. ```ruby gem 'blueprinter' ``` -------------------------------- ### Render as Hash Example Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Use `render_as_hash` to get a Ruby Hash representation of the blueprint. Requires the UserBlueprint class to be defined. ```ruby puts UserBlueprint.render_as_hash(user, company: company) ``` -------------------------------- ### Example User Class with Dynamic Fields Source: https://github.com/procore-oss/blueprinter/blob/main/README.md An example `User` class demonstrating a `dynamic_fields` method that returns different data based on the user's role, intended for use with transformers. ```ruby class User def dynamic_fields case role when :admin { employer: employer, time_in_role: determine_time_in role } when :maintainer { label: label, settings: generate_settings_hash } when :read_only { last_login_at: last_login_at } end end end ``` -------------------------------- ### Render as JSON Example Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Use `render_as_json` to get a JSON string representation of the blueprint. Requires the UserBlueprint class to be defined. ```ruby puts UserBlueprint.render_as_json(user, company: company) ``` -------------------------------- ### JSON with Root and Meta Keys Source: https://github.com/procore-oss/blueprinter/wiki/1.0-Roadmap Example of a JSON structure supporting both a root key for data and meta keys for additional information. ```json { "data": [{...}, {...}, {...}], "totals": 3 } ``` -------------------------------- ### Field-level/Association-level Setting - EMPTY_STRING Source: https://github.com/procore-oss/blueprinter/blob/main/README.md This example demonstrates how to render a User blueprint with associated draft projects. It shows passing a collection to the render method. ```ruby puts UserBlueprint.render(user, draft_projects: Project.where(draft: true)) ``` -------------------------------- ### JSON with Root Key Source: https://github.com/procore-oss/blueprinter/wiki/1.0-Roadmap Example of a JSON structure supporting a root key for data. ```json { "data": {"first_name": "Bob", "last_name": "Smith"} } ``` -------------------------------- ### Configure Blueprinter to use Oj for JSON generation Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Set Blueprinter's generator to Oj for potentially faster JSON generation. Ensure the 'oj' gem is installed and required. ```ruby require 'oj' # you can skip this if OJ has already been required. Blueprinter.configure do |config| config.generator = Oj # default is JSON end ``` -------------------------------- ### Get Field Information Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Inspect individual field objects obtained from blueprint reflections to access their name, display name, and options. ```ruby # Get info about a field fields[:description].name fields[:description].display_name fields[:description].options ``` -------------------------------- ### Inspecting Blueprint Structure with `reflections` Source: https://context7.com/procore-oss/blueprinter/llms.txt Use `Blueprinter::Base.reflections` to get a hash of `Blueprinter::Reflection::View` objects. This allows runtime introspection of fields and associations within different blueprint views. ```ruby class WidgetBlueprint < Blueprinter::Base identifier :id fields :name, :description association :category, blueprint: CategoryBlueprint view :extended do field :price association :parts, blueprint: PartBlueprint end end views = WidgetBlueprint.reflections views.keys # => [:identifier, :default, :extended] default_view = views[:default] # Inspect fields default_view.fields.keys # => [:name, :description] field_info = default_view.fields[:name] field_info.name # => :name field_info.display_name # => :name field_info.options # => {} # Inspect associations default_view.associations.keys # => [:category] assoc_info = default_view.associations[:category] assoc_info.blueprint # => CategoryBlueprint assoc_info.view # => :default assoc_info.display_name # => :category # Extended view extended = views[:extended] extended.fields.keys # => [:name, :description, :price] extended.associations.keys # => [:category, :parts] ``` -------------------------------- ### Inspect Blueprint Views Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Access blueprint reflections to get a hash of all defined views, keyed by their names. This is useful for understanding the structure of a blueprint. ```ruby # A Hash of views keyed by name views = WidgetBlueprint.reflections views.keys # => [:default, :extended] ``` -------------------------------- ### Configure Blueprinter to use Yajl-ruby for JSON generation Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Set Blueprinter's generator to Yajl::Encoder for JSON generation. Specify the method as :encode. Ensure 'yajl-ruby' is installed. ```ruby require 'yajl' # you can skip this if yajl has already been required. Blueprinter.configure do |config| config.generator = Yajl::Encoder # default is JSON config.method = :encode # default is generate end ``` -------------------------------- ### Get Association Information Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Inspect individual association objects obtained from blueprint reflections to access their name, display name, associated blueprint, view, and options. ```ruby # Get info about an association assoc[:category].name assoc[:category].display_name assoc[:category].blueprint assoc[:category].view assoc[:category].options ``` -------------------------------- ### Define and Render Views with Blueprinter Source: https://context7.com/procore-oss/blueprinter/llms.txt Demonstrates how to define different views for a blueprint and render objects using a specified view. Useful for controlling the output structure based on context. ```ruby class UserBlueprint < Blueprinter::Base field :uuid field :first_name field :last_name field :email field :address field :phone view :admin do field :internal_notes field :role end end UserBlueprint.render(user) # => '{"uuid":"...","first_name":"Jane","last_name":"Doe","email":"...","address":"...","phone":"..."}' UserBlueprint.render(user, view: :admin) # => '{"uuid":"...","first_name":"Jane","last_name":"Doe","email":"...","internal_notes":"...","role":"admin"}' ``` -------------------------------- ### Applying Multiple Transformers Across Views Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Demonstrates how to apply transformers globally and per-view. Transformers are executed in the order they are defined, from top-down. ```ruby class UserBlueprint < Blueprinter::Base transform DefaultTransformer view :normal do transform ViewTransformer end view :extended do include_view :normal end end ``` -------------------------------- ### Define User Blueprint with Views Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Define a blueprint with multiple views to control which fields and associations are rendered. Views can include fields from other views using `include_view`. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field :email, name: :login view :normal do fields :first_name, :last_name end view :extended do include_view :normal field :address association :projects end end ``` -------------------------------- ### Inherit Blueprints with Ruby Source: https://github.com/procore-oss/blueprinter/wiki/1.0-Roadmap Demonstrates how blueprints can inherit identifiers and fields from a superclass. ```ruby class ApplicationBlueprint < Blueprinter::Base identifier :uuid end class UserBlueprint < ApplicationBlueprint # identifier :uuid should be inherited from the super class. fields :name end ``` -------------------------------- ### Create a Pre-Render Extension Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Implement a custom extension by subclassing Blueprinter::Extension and overriding the `pre_render` hook. This hook allows modification of the object before serialization. ```ruby class ObfuscateNameExtension < Blueprinter::Extension def pre_render(object, blueprint, view, options) return object unless object.respond_to?(:name) modified_object = object.dup modified_object.name = ObsfuscateName.call(modified_object.name) modified_object end end ``` -------------------------------- ### Render a Single User Object Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Render a single user object using the defined blueprint. The output is a JSON string. ```ruby puts UserBlueprint.render(user) ``` -------------------------------- ### Define Extension Execution Order Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Specify the order in which extensions are applied by adding them to the `config.extensions` array in the desired sequence. Extensions are executed in the order they are added. ```ruby Blueprinter.configure do |config| config.extensions << SecurityExtension.new # Runs first config.extensions << AssociationLoaderExtension.new # Runs second config.extensions << UserEnrichmentExtension.new # Runs third end ``` -------------------------------- ### Render User Object with Meta Attributes Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Render a user object with meta-attributes, including a root key and a meta object. A root key is mandatory when using meta attributes. ```ruby json = UserBlueprint.render(user, view: :normal, root: :user, meta: {links: [ 'https://app.mydomain.com', 'https://alternate.mydomain.com' ]}) ``` ```ruby puts json ``` -------------------------------- ### Configure Custom Array-Like Classes Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Configure Blueprinter to treat specific classes, like Mongoid::Criteria or Set, as collections for rendering purposes. ```ruby Blueprinter.configure do |config| config.custom_array_like_classes = [Mongoid::Criteria] end ``` ```ruby Blueprinter.configure do |config| config.custom_array_like_classes = [Set] end ``` -------------------------------- ### Configure Blueprinter Globally Source: https://context7.com/procore-oss/blueprinter/llms.txt Set library-wide defaults using `Blueprinter.configure`. This is typically done in an initializer file to customize JSON generation, field defaults, datetime formats, and more. ```ruby # config/initializers/blueprinter.rb Blueprinter.configure do |config| # Use Oj for faster JSON generation config.generator = Oj config.method = :dump # Global field/association defaults when value is nil config.field_default = "N/A" config.association_default = {} # Global datetime format config.datetime_format = ->(dt) { dt.nil? ? nil : dt.strftime("%Y-%m-%dT%H:%M:%SZ") } # Sort fields in definition order instead of alphabetically config.sort_fields_by = :definition # Global conditional: omit fields whose value is nil config.if = ->(_field_name, obj, _opts) { !obj.nil? } # Deprecation reporting: :stderror (default), :raise, :silence config.deprecations = :raise # Treat Mongoid::Criteria and Set as array-like collections config.custom_array_like_classes = [Mongoid::Criteria, Set] # Global default transformers applied to every blueprint config.default_transformers = [LowerCamelTransformer] # Custom extractor config.extractor_default = MyAutoExtractor # Register extensions config.extensions << AuditLogExtension.new config.extensions << CachingExtension.new end ``` -------------------------------- ### Check View Definition with `view?` Source: https://context7.com/procore-oss/blueprinter/llms.txt Use the `view?` method to check if a blueprint defines a specific view. This is helpful for conditional rendering logic before attempting to render with a dynamic view name. ```ruby class ReportBlueprint < Blueprinter::Base identifier :id view :summary do fields :title, :total end end ReportBlueprint.view?(:summary) # => true ReportBlueprint.view?(:missing) # => false view_name = params[:view]&.to_sym || :default if ReportBlueprint.view?(view_name) ReportBlueprint.render(report, view: view_name) else render json: { error: "Unknown view" }, status: :bad_request end ``` -------------------------------- ### Define a Basic User Blueprint Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Define a simple blueprint for a User object, specifying the identifier and fields to be rendered. This is useful for basic JSON serialization. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid fields :first_name, :last_name, :email end ``` -------------------------------- ### Blueprint Definition with Fields and Associations Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Define a Blueprint class with basic fields and associations. This serves as a base for reflection and can be extended with views. ```ruby class WidgetBlueprint < Blueprinter::Base fields :name, :description association :category, blueprint: CategoryBlueprint view :extended do field :price association :parts, blueprint: WidgetPartBlueprint end end ``` -------------------------------- ### View Git Remotes Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Run this command to list all configured remote repositories for your local Git repository and identify the previous remote name. ```bash git remote -v ``` -------------------------------- ### Render a Collection of User Objects Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Render a collection or array of user objects. This will result in a JSON array of serialized objects. ```ruby puts UserBlueprint.render(User.all) ``` -------------------------------- ### Define User Blueprint with Identifier Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Define a blueprint specifying a field to be used as the unique identifier. Identifiers are always rendered and sorted first. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid end ``` -------------------------------- ### Global Datetime Formatting Configuration Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Set a global `datetime_format` Proc to format all fields that respond to `strftime`. The Proc should handle `nil` values and return the formatted string or integer. ```ruby Blueprinter.configure do |config| config.datetime_format = ->(datetime) { datetime.nil? ? datetime : datetime.strftime("%s").to_i } end ``` -------------------------------- ### Add Extensions to Blueprinter Configuration Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Configure Blueprinter to use custom extensions by adding instances of extension classes to the `config.extensions` array. Extensions modify blueprint behavior. ```ruby Blueprinter.configure do |config| config.extensions << MyExtension.new config.extensions << OtherExtension.new end ``` -------------------------------- ### Blueprinter::Base.render_as_json Source: https://context7.com/procore-oss/blueprinter/llms.txt Returns a hash where all keys are converted to strings and values are JSONified. Useful as an intermediate form compatible with JSON-oriented tooling. ```APIDOC ## Blueprinter::Base.render_as_json — Render object to JSONified hash ### Description Returns a hash where all keys are converted to strings and values are JSONified (similar to `as_json` in Rails). Useful as an intermediate form compatible with JSON-oriented tooling. ### Method `Blueprinter::Base.render_as_json(object, options = {})` ### Parameters #### Options - **view** (Symbol, optional): Selects a named view defined in the Blueprint. - **root** (Symbol or String, optional): Wraps the output in a top-level key. - **meta** (Hash, optional): Attaches metadata alongside the root key. ### Request Example ```ruby # Assuming OrderBlueprint is defined as in the documentation order = Order.new(...) OrderBlueprint.render_as_json(order) ``` ### Response #### Success Response (Hash) Returns a JSONified Hash representing the serialized object. #### Response Example ```json { "id": 7, "total": 49.95, "status": "shipped" } ``` ``` -------------------------------- ### Passing Additional Properties to #render Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Use the options hash in the `render` method to pass additional properties. These properties can then be accessed within `field` blocks using the `options` argument. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field(:company_name) do |_user, options| options[:company].name end end ``` ```ruby puts UserBlueprint.render(user, company: company) ``` -------------------------------- ### Render User Object with Root Key Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Render a user object with a specified root key to wrap the resulting JSON. This is useful for structuring the top-level JSON object. ```ruby puts UserBlueprint.render(user, view: :normal, root: :user) ``` -------------------------------- ### Render User Object Using a Specific View Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Render a user object using a specific view (e.g., `:extended`). This allows for selective serialization based on the defined views. ```ruby puts UserBlueprint.render(user, view: :extended) ``` -------------------------------- ### Render Object to JSON String with Blueprinter Source: https://context7.com/procore-oss/blueprinter/llms.txt Use `Blueprinter::Base.render` to serialize single objects or collections to a JSON string. Options include selecting named views, adding a root key, and attaching metadata. Extra options are passed to field blocks and transformers. ```ruby class AddressBlueprint < Blueprinter::Base identifier :id fields :street, :city, :zip end class UserBlueprint < Blueprinter::Base identifier :uuid fields :email, :created_at view :normal do fields :first_name, :last_name end view :extended do include_view :normal field :phone association :address, blueprint: AddressBlueprint end end user = User.new(uuid: "abc-123", email: "jane@example.com", first_name: "Jane", last_name: "Doe", phone: "555-0100", created_at: Time.now, address: Address.new(id: 1, street: "1 Main St", city: "Springfield", zip: "12345")) # Default view (only identifier + fields declared outside a view block) UserBlueprint.render(user) # => '{"uuid":"abc-123","email":"jane@example.com","created_at":"2024-01-15T10:00:00Z"}' # Named view UserBlueprint.render(user, view: :normal) # => '{"uuid":"abc-123","email":"jane@example.com","created_at":"...","first_name":"Jane","last_name":"Doe"}' # Extended view with association UserBlueprint.render(user, view: :extended) # => '{"uuid":"abc-123","email":"...","first_name":"Jane","last_name":"Doe","phone":"555-0100","address":{"id":1,"street":"1 Main St","city":"Springfield","zip":"12345"}}' # With root key and meta UserBlueprint.render(user, view: :normal, root: :user, meta: { version: "v1" }) # => '{"user":{"uuid":"abc-123",...},"meta":{"version":"v1"}}' # Collections UserBlueprint.render(User.all, view: :normal) # => '[{"uuid":"abc-123",...},{"uuid":"def-456",...}]' ``` -------------------------------- ### Implement Custom Field Extraction Source: https://context7.com/procore-oss/blueprinter/llms.txt Create custom extractors by subclassing `Blueprinter::Extractor` and implementing `#extract`. Assign globally via `config.extractor_default` or per-field/association using the `:extractor` option. ```ruby class MyAutoExtractor < Blueprinter::Extractor def extract(field_name, object, options) # Custom extraction logic here end end # Global configuration Blueprinter.configure do |config| config.extractor_default = MyAutoExtractor end # Per-field configuration class UserBlueprint < Blueprinter::Base field :name, extractor: MyCustomNameExtractor end ``` -------------------------------- ### Blueprinter::Base.render Source: https://context7.com/procore-oss/blueprinter/llms.txt Serializes a single object or collection to a JSON-formatted string. Supports optional `view:`, `root:`, and `meta:` keys for customization. Extra options are passed to field blocks and transformers. ```APIDOC ## Blueprinter::Base.render — Render object to JSON string ### Description Serializes a single object or collection to a JSON-formatted string. Accepts an optional `view:` key to select a named field group, a `root:` key to wrap the output in a top-level key, and a `meta:` key to attach metadata alongside the root key. Any extra key/value pairs in the options hash are passed through to field blocks and transformers. ### Method `Blueprinter::Base.render(object, options = {})` ### Parameters #### Options - **view** (Symbol, optional): Selects a named view defined in the Blueprint. - **root** (Symbol or String, optional): Wraps the output in a top-level key. - **meta** (Hash, optional): Attaches metadata alongside the root key. ### Request Example ```ruby # Assuming UserBlueprint and AddressBlueprint are defined as in the documentation user = User.new(...) # Default view UserBlueprint.render(user) # Named view UserBlueprint.render(user, view: :normal) # Extended view with association UserBlueprint.render(user, view: :extended) # With root key and meta UserBlueprint.render(user, view: :normal, root: :user, meta: { version: "v1" }) # Collections UserBlueprint.render(User.all, view: :normal) ``` ### Response #### Success Response (String) Returns a JSON-formatted string representing the serialized object or collection. #### Response Example ```json '{"uuid":"abc-123","email":"jane@example.com","created_at":"2024-01-15T10:00:00Z"}' ``` ``` -------------------------------- ### Blueprinter::Base.render_as_hash Source: https://context7.com/procore-oss/blueprinter/llms.txt Returns a plain Ruby Hash (or Array of hashes for collections) instead of a JSON string. Accepts the same options as `render`. Useful for further manipulation before serialization. ```APIDOC ## Blueprinter::Base.render_as_hash — Render object to Ruby hash ### Description Returns a plain Ruby `Hash` (or `Array` of hashes for collections) instead of a JSON string. Accepts the same options as `render`. Useful when the result needs further manipulation before serialization. ### Method `Blueprinter::Base.render_as_hash(object, options = {})` ### Parameters #### Options - **view** (Symbol, optional): Selects a named view defined in the Blueprint. - **root** (Symbol or String, optional): Wraps the output in a top-level key. - **meta** (Hash, optional): Attaches metadata alongside the root key. ### Request Example ```ruby # Assuming ProductBlueprint is defined as in the documentation product = Product.new(...) result = ProductBlueprint.render_as_hash(product) # Collections ProductBlueprint.render_as_hash(Product.all) ``` ### Response #### Success Response (Hash) Returns a Ruby Hash (or Array of Hashes for collections) representing the serialized object. #### Response Example ```ruby { id: 42, name: "Widget", price: 9.99, stock: 100 } ``` ``` -------------------------------- ### Field-Level Datetime Formatting (Proc) Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Use a `datetime_format` Proc for a specific field to define custom formatting logic, including handling `nil` values. This overrides global settings for the field. ```ruby class UserBlueprint < Blueprinter::Base identifier :name field :birthday, datetime_format: ->(datetime) { datetime.nil? ? datetime : datetime.strftime("%s").to_i } end ``` -------------------------------- ### Configure Field Sorting by Definition Order Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Change the default behavior of sorting blueprint fields alphabetically by name. This configuration ensures fields are output in the order they are defined in the blueprint. ```ruby Blueprinter.configure do |config| config.sort_fields_by = :definition end ``` -------------------------------- ### Render Object to Ruby Hash with Blueprinter Source: https://context7.com/procore-oss/blueprinter/llms.txt Use `Blueprinter::Base.render_as_hash` to serialize objects or collections into plain Ruby hashes. This method accepts the same options as `render` and is useful for further data manipulation before final serialization. ```ruby class ProductBlueprint < Blueprinter::Base identifier :id fields :name, :price, :stock end product = Product.new(id: 42, name: "Widget", price: 9.99, stock: 100) result = ProductBlueprint.render_as_hash(product) # => { id: 42, name: "Widget", price: 9.99, stock: 100 } result[:name] # => "Widget" # Collections ProductBlueprint.render_as_hash(Product.all) # => [{ id: 42, name: "Widget", price: 9.99, stock: 100 }, ...] ``` -------------------------------- ### Inspect Blueprint Fields and Associations Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Retrieve hashes of fields and associations from a specific blueprint view. This allows programmatic inspection of the blueprint's structure. ```ruby # Hashes of fields and associations, keyed by name fields = views[:default].fields assoc = views[:default].associations ``` -------------------------------- ### Define User Blueprint with Renamed Fields and Associations Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Define a blueprint that renames JSON keys for fields and associations using the `name` option. This allows for more control over the output JSON structure. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field :email, name: :login association :user_projects, name: :projects end ``` -------------------------------- ### Declare Multiple Fields at Once Source: https://context7.com/procore-oss/blueprinter/llms.txt A shorthand for declaring several plain fields without options in a single call. ```ruby class ArticleBlueprint < Blueprinter::Base identifier :id fields :title, :body, :published_at, :author_name view :summary do fields :title, :author_name end end ``` ```ruby ArticleBlueprint.render(article, view: :summary) # => '{"id":1,"title":"Hello World","author_name":"Jane Doe"}' ``` -------------------------------- ### Intercept Objects with `pre_render` Extension Hook Source: https://context7.com/procore-oss/blueprinter/llms.txt Create custom extensions by subclassing `Blueprinter::Extension` and overriding `pre_render`. This hook allows modification of objects before rendering, useful for sanitization or scoping. ```ruby class SanitizeExtension < Blueprinter::Extension def pre_render(object, blueprint, view, options) return object unless object.respond_to?(:name) sanitized = object.dup sanitized.name = HtmlSanitizer.strip(sanitized.name) sanitized end end class CurrentUserScopeExtension < Blueprinter::Extension def pre_render(object, _blueprint, _view, options) current_user = options[:current_user] return object unless current_user && object.respond_to?(:scoped_for) object.scoped_for(current_user) end end Blueprinter.configure do |config| config.extensions << SanitizeExtension.new config.extensions << CurrentUserScopeExtension.new end # Extensions are invoked automatically on every render call UserBlueprint.render(user, current_user: current_user) ``` -------------------------------- ### Render Object to JSONified Hash with Blueprinter Source: https://context7.com/procore-oss/blueprinter/llms.txt Use `Blueprinter::Base.render_as_json` to obtain a hash where keys are strings and values are JSONified, similar to Rails' `as_json`. This is suitable for intermediate processing with JSON-oriented tools. ```ruby class OrderBlueprint < Blueprinter::Base identifier :id fields :total, :status end order = Order.new(id: 7, total: 49.95, status: :shipped) OrderBlueprint.render_as_json(order) # => { "id" => 7, "total" => 49.95, "status" => "shipped" } ``` -------------------------------- ### Include Associations in Blueprinter Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Render associated objects by defining them using the `association` method. Options can be passed to nested blueprints. ```ruby class ProjectBlueprint < Blueprinter::Base identifier :uuid field :name end class UserBlueprint < Blueprinter::Base identifier :uuid field :email, name: :login view :normal do fields :first_name, :last_name association :projects, blueprint: ProjectBlueprint end end ``` ```ruby puts UserBlueprint.render(user, view: :normal) ``` ```ruby class VehicleBlueprint < Blueprinter::Base identifier :uuid field :full_name do |vehicle, options| "#{vehicle.model} #{options[:trim]}" end end class DriverBlueprint < Blueprinter::Base identifier :uuid view :normal do fields :first_name, :last_name association :vehicles, blueprint: VehicleBlueprint, options: { trim: 'LX' } end end ``` ```ruby class DriverBlueprint < Blueprinter::Base identifier :uuid view :normal do fields :first_name, :last_name association :vehicles, blueprint: VehicleBlueprint, options: ->(driver) { { trim: driver.preferred_trim } } end end ``` -------------------------------- ### Configure Global Field and Association Defaults Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Set default values for all fields and associations globally using Blueprinter.configure. This affects all blueprints unless overridden. ```ruby Blueprinter.configure do |config| config.field_default = "N/A" config.association_default = {} end ``` -------------------------------- ### Global Conditional Field Rendering Configuration Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Configure global `if` and `unless` Procs to control field rendering based on object properties. These can be overridden at the field level. ```ruby Blueprinter.configure do |config| config.if = ->(field_name, obj, _options) { !obj[field_name].nil? } config.unless = ->(field_name, obj, _options) { obj[field_name].nil? } end ``` -------------------------------- ### Set Global Default Transformers Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Configure Blueprinter to use a list of default transformers globally. Any transforms specified at a per-blueprint or per-view level will override these defaults. ```ruby Blueprinter.configure do |config| config.default_transformers = [LowerCamelTransformer] end ``` -------------------------------- ### Set Default for Empty String or Collection Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Use `default_if` with `Blueprinter::EMPTY_STRING` or `Blueprinter::EMPTY_COLLECTION` to set default values when fields are empty strings or associations are empty collections. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid view :normal do # If first_name is an empty string, it will become "N/A" field :first_name, default_if: Blueprinter::EMPTY_STRING, default: "N/A" # If the projects association collection is empty, it will become nil association :projects, blueprint: ProjectBlueprint, default_if: Blueprinter::EMPTY_COLLECTION end end ``` -------------------------------- ### Using `default_if` with Empty Type Constants Source: https://context7.com/procore-oss/blueprinter/llms.txt Configure fields and associations to treat specific empty values (collections, hashes, strings) as `nil` using `default_if` and Blueprinter's empty type constants. This allows a default value to be applied when these empty values are encountered. ```ruby class ProfileBlueprint < Blueprinter::Base identifier :id field :bio, default: "No bio available", default_if: Blueprinter::EMPTY_STRING association :projects, blueprint: ProjectBlueprint, default: [], default_if: Blueprinter::EMPTY_COLLECTION field :metadata, default: { locale: "en" }, default_if: Blueprinter::EMPTY_HASH end user_with_empty = User.new(id: 3, bio: "", projects: [], metadata: {}) ProfileBlueprint.render(user_with_empty) # => '{"id":3,"bio":"No bio available","projects":[],"metadata":{"locale":"en"}}' ``` -------------------------------- ### Dynamic Blueprint for Polymorphic Associations Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Dynamically evaluate the blueprint for associations, useful for polymorphic associations. Ensure the object's `blueprint` method returns a valid Blueprint class. `has_many` is not currently supported for polymorphic associations. ```ruby class Task < ActiveRecord::Base belongs_to :taskable, polymorphic: true end class Project < ActiveRecord::Base has_many :tasks, as: :taskable def blueprint ProjectBlueprint end end class TaskBlueprint < Blueprinter::Base identifier :uuid view :normal do field :title, default: "N/A" association :taskable, blueprint: ->(taskable) {taskable.blueprint}, default: {} end end ``` -------------------------------- ### Set Field and Association Defaults in Blueprint Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Define default values for specific fields and associations within a blueprint. This allows for fine-grained control over defaults per blueprint. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid view :normal do field :first_name, default: "N/A" association :company, blueprint: CompanyBlueprint, default: {} end end ``` -------------------------------- ### Exclude Fields in Blueprinter View Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Define views to selectively include or exclude fields. Use `exclude` for single fields or `excludes` for multiple fields within a specific view. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field :email, name: :login view :normal do fields :first_name, :last_name end view :extended do include_view :normal field :address exclude :last_name end end ``` ```ruby puts UserBlueprint.render(user, view: :extended) ``` ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field :email, name: :login view :normal do fields :age, :first_name, :last_name, end view :extended do include_view :normal field :address excludes :age, :last_name end end ``` -------------------------------- ### Blueprint Inheritance for Shared Definitions Source: https://context7.com/procore-oss/blueprinter/llms.txt Blueprints inherit fields, views, and associations from parent classes. This is useful for establishing a common `ApplicationBlueprint` with shared identifiers and views. ```ruby class ApplicationBlueprint < Blueprinter::Base identifier :id view :timestamped do fields :created_at, :updated_at end end class UserBlueprint < ApplicationBlueprint fields :email, :role view :profile do include_view :timestamped fields :first_name, :last_name, :avatar_url end end class PostBlueprint < ApplicationBlueprint fields :title, :body view :summary do fields :title end end UserBlueprint.render(user, view: :profile) # => '{"id":1,"email":"jane@example.com","role":"admin","first_name":"Jane","last_name":"Doe","avatar_url":"...","created_at":"...","updated_at":"..."}' ``` -------------------------------- ### Define Field with Symbol#to_proc Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Use `Symbol#to_proc` as a shorthand for blocks that delegate to a single method. This bypasses `options` and the configured extractor. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field :display_name, &:formatted_full_name end ``` -------------------------------- ### Define Identifier with Symbol#to_proc Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Use `Symbol#to_proc` as a shorthand for identifiers that simply call a single method on the object. This bypasses `options` and the configured extractor. ```ruby class UserBlueprint < Blueprinter::Base identifier :anonymized_id, &:obfuscated_uuid end ``` -------------------------------- ### Applying a Transformer to a Blueprint Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Specify a transformer class to be used for a blueprint. The transformer's `transform` method will be called during serialization to modify the output hash. ```ruby class UserBlueprint < Blueprinter::Base fields :first_name, :last_name transform DynamicTransformer end ``` -------------------------------- ### Configure Deprecation Reporting Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Set the deprecation reporting level. Options are :stderr (default), :raise, or :silence. ```ruby Blueprinter.configure do |config| config.deprecations = :raise end ``` -------------------------------- ### Define Global Auto Extractor Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Create a custom auto-extractor class extending Blueprinter::AutoExtractor to provide a global default extractor. This class can dispatch to other extractors based on object type or conditions. ```ruby class MyAutoExtractor < Blueprinter::AutoExtractor def initialize super @my_field_extractor = MyFieldExtractor.new end def extractor(object, options) # dispatch to any class AutoExtractor can, plus more if detect_obscurity(object) @my_field_extractor else super end end end ``` -------------------------------- ### Declare Single Serialized Field Source: https://context7.com/procore-oss/blueprinter/llms.txt Adds a field to the current or default view. Supports renaming, conditional inclusion, datetime formatting, default values, and computed blocks. ```ruby class UserBlueprint < Blueprinter::Base identifier :id # Simple field field :email # Renamed field field :email, name: :login # Computed field with block field :full_name do |user, options| "#{options[:title]} #{user.first_name} #{user.last_name}" end # Symbol#to_proc shorthand (no options access) field :display_name, &:formatted_full_name # Conditional inclusion field :admin_notes, if: ->(_name, user, _opts) { user.admin? } field :ssn, unless: :hide_sensitive? # DateTime formatting field :created_at, datetime_format: "%Y-%m-%d" field :updated_at, datetime_format: ->(dt) { dt.to_i } # Default value when nil field :nickname, default: "Anonymous" # Treat empty string as nil and apply default field :bio, default: "No bio provided", default_if: Blueprinter::EMPTY_STRING # Exclude the field from output when nil field :optional_note, exclude_if_nil: true def hide_sensitive?(_field_name, user, _options) !user.admin? end end ``` ```ruby UserBlueprint.render(user, title: "Dr.") # => '{"id":1,"email":"jane@example.com","full_name":"Dr. Jane Doe","created_at":"2024-01-15",...}' ``` -------------------------------- ### Define Field with a Block Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Define a field directly in the Blueprint using a block, useful when the object doesn't have the attribute or method. The block yields the object and any options passed from `render`. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field :full_name do |user, options| "#{options[:title_prefix]} #{user.first_name} #{user.last_name}" end end ``` -------------------------------- ### Define Custom Field Extractor Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Create a custom extractor class by extending Blueprinter::Extractor to define how a specific field's value is retrieved from an object. This can be applied per-field. ```ruby class MyFieldExtractor < Blueprinter::Extractor def extract(_field_name, _object, _local_options, _options={}) # process your obscure_object _object.clarified end end ``` -------------------------------- ### Access View Option in Field Block Source: https://github.com/procore-oss/blueprinter/blob/main/README.md The `view` option passed to `render` is available in the `options` hash within a `field` block. This allows conditional logic based on the active view. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field :full_name do |user, options| prefix = options[:view] == :admin ? '[Admin]' : options[:title_prefix] "#{prefix} #{user.first_name} #{user.last_name}" end view :admin do field :access_level end end ``` -------------------------------- ### Define Identifier with a Block Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Pass a block to an identifier to dynamically determine its value. The block receives the object and `options`. This is useful for anonymizing or transforming identifiers. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid do |user, options| options[:current_user].anonymize(user.uuid) end end ``` -------------------------------- ### Use Custom Extractor in Blueprint Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Specify a custom extractor for a field within a Blueprint class. This allows for specialized data retrieval logic for individual fields. ```ruby class MysteryBlueprint < Blueprinter::Base field :obscure_object, extractor: MyFieldExtractor end ``` -------------------------------- ### Apply Post-processing with Transformers Source: https://context7.com/procore-oss/blueprinter/llms.txt Register transformer classes to modify the serialized hash after field extraction. Transformers are applied top-down and can be defined globally or per-view. ```ruby class LowerCamelTransformer < Blueprinter::Transformer def transform(hash, _object, _options) hash.transform_keys! { |key| key.to_s.camelize(:lower).to_sym } end end class DynamicFieldTransformer < Blueprinter::Transformer def transform(hash, object, _options) hash.merge!(object.dynamic_attributes) end end class UserBlueprint < Blueprinter::Base transform LowerCamelTransformer # applied to default view and all views fields :first_name, :last_name view :extended do transform DynamicFieldTransformer # applied after LowerCamelTransformer field :department end end UserBlueprint.render(user, view: :extended) # => '{"firstName":"Jane","lastName":"Doe","department":"Engineering","custom_flag":true}' ``` -------------------------------- ### Custom Transformer Class Definition Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Define a custom transformer class by inheriting from `Blueprinter::Transformer` and implementing the `transform` method. This method modifies the hash before serialization. ```ruby class DynamicFieldTransformer < Blueprinter::Transformer def transform(hash, object, _options) hash.merge!(object.dynamic_fields) end end ``` -------------------------------- ### Define a Named View Source: https://context7.com/procore-oss/blueprinter/llms.txt Groups fields, associations, and transformers under a named scope. Views are referenced at render time and can compose or override other views. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid view :normal do fields :first_name, :last_name, :email end view :compact do field :first_name end view :extended do include_views :normal, :compact # merge multiple views field :address field :phone exclude :first_name # remove a field merged from :compact end view :admin do include_view :extended fields :internal_notes, :role excludes :phone, :address # exclude multiple fields at once end end ``` ```ruby UserBlueprint.render(user, view: :extended) ``` -------------------------------- ### Define Global Lower Camel Case Transformer Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Create a custom transformer class that extends Blueprinter::Transformer to convert keys to lower camel case. This transformer can be set as a global default. ```ruby class LowerCamelTransformer < Blueprinter::Transformer def transform(hash, _object, _options) hash.transform_keys! { |key| key.to_s.camelize(:lower).to_sym } end end ``` -------------------------------- ### Field-Level Datetime Formatting (String) Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Specify a `datetime_format` string using `strftime` syntax for a specific field. This overrides any global datetime format setting for that field. ```ruby class UserBlueprint < Blueprinter::Base identifier :name field :birthday, datetime_format: "%m/%d/%Y" end ``` -------------------------------- ### Set Global Default Extractor Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Configure Blueprinter to use a specific auto-extractor class as the global default. This affects how fields are extracted across all blueprints unless overridden. ```ruby Blueprinter.configure do |config| config.extractor_default = MyAutoExtractor end ``` -------------------------------- ### Define Association with a Block Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Pass a block to an association to dynamically determine the collection of associated objects. The block receives the object and `options`, allowing for custom logic like merging collections. ```ruby class ProjectBlueprint < Blueprinter::Base identifier :uuid field :name end class UserBlueprint < Blueprinter::Base identifier :uuid association :projects, blueprint: ProjectBlueprint do |user, options| user.projects + options[:draft_projects] end end ``` -------------------------------- ### Field-Level Conditional Rendering Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Apply `if` or `unless` Procs directly to fields to conditionally render them based on object data or options. This overrides global settings for the specific field. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field :last_name, if: ->(_field_name, user, options) { user.first_name != options[:first_name] } field :age, unless: ->(_field_name, user, _options) { user.age < 18 } end ``` -------------------------------- ### Update Git Remote URL Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Use this command to update your local Git repository's remote URL to the new GitHub location. ```bash git remote set-url [previous-remote-name] git@github.com:procore-oss/blueprinter.git ``` -------------------------------- ### Exclude Fields with Nil Values Source: https://github.com/procore-oss/blueprinter/blob/main/README.md Set `:exclude_if_nil: true` on a field to prevent it from being included in the output if its value is `nil`. This is useful for cleaning up JSON output. ```ruby class UserBlueprint < Blueprinter::Base identifier :uuid field :name field :birthday, exclude_if_nil: true end user = User.new(name: 'John Doe') puts UserBlueprint.render(user) ``` -------------------------------- ### Declare Primary Identifier Field Source: https://context7.com/procore-oss/blueprinter/llms.txt Marks a field as the object's identifier. Identifiers are always included and sorted first. Supports renaming and computed values. ```ruby class UserBlueprint < Blueprinter::Base # Simple identifier identifier :uuid # Renamed identifier identifier :uuid, name: :user_id # Computed identifier with block identifier :uuid do |user, options| options[:current_user].anonymize(user.uuid) end # Symbol#to_proc shorthand identifier :anonymized_id, &:obfuscated_uuid end ``` ```ruby UserBlueprint.render(user) # => '{"uuid":"733f0758-8f21-4719-875f-262c3ec743af",...}' ``` -------------------------------- ### Custom I18nExtractor for Locale-Aware Fields Source: https://context7.com/procore-oss/blueprinter/llms.txt Use a custom extractor to read locale-specific translated attributes from an object. Ensure the object responds to `translated_attribute` and locale is available in `local_options` or `I18n.locale`. ```ruby class I18nExtractor < Blueprinter::Extractor def extract(field_name, object, local_options, _options = {}) locale = local_options[:locale] || I18n.locale object.translated_attribute(field_name, locale) end end class ProductBlueprint < Blueprinter::Base identifier :id field :name, extractor: I18nExtractor field :description, extractor: I18nExtractor field :price end ProductBlueprint.render(product, locale: :fr) # => '{"id":10,"name":"Gadget (FR)","description":"Un gadget utile","price":29.99}' ``` -------------------------------- ### Declare Nested Association Source: https://context7.com/procore-oss/blueprinter/llms.txt Embeds a related object or collection using a child blueprint. Requires the `:blueprint` option and supports renaming, specific child views, options, and custom data resolution. ```ruby class CategoryBlueprint < Blueprinter::Base identifier :id fields :name end class TagBlueprint < Blueprinter::Base identifier :id fields :label end class PostBlueprint < Blueprinter::Base identifier :id fields :title # Basic association association :category, blueprint: CategoryBlueprint # Renamed association using a specific child view association :tags, blueprint: TagBlueprint, name: :post_tags, view: :default # Static nested options association :comments, blueprint: CommentBlueprint, options: { include_deleted: false } # Dynamic nested options based on parent object association :attachments, blueprint: AttachmentBlueprint, options: ->(post) { { owner_id: post.author_id } } # Block to compute the associated data association :related_posts, blueprint: PostBlueprint do |post, options| post.related + options[:sponsored_posts] end end ``` ```ruby PostBlueprint.render(post, sponsored_posts: Post.where(sponsored: true)) # => '{"id":5,"title":"Hello","category":{"id":2,"name":"Tech"},"post_tags":[{"id":1,"label":"ruby"}],...}' ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.