GithubHelp home page GithubHelp logo

frontier_generators's Introduction

Frontier Generators

Use the Frontier Generators on the Frontier Template to quickly spin up CRUD interfaces.

By default, you get:

  • Models with validations
  • Factories for models using FFaker. Factoried attributes take validations into account.
  • Index, new, edit, destroy actions
  • Authorization via CanCanCan abilities or Pundit policies
  • Feature and unit tests for all of the above
  • Empty seed rake task

Important Caveat: In Progress

This gem is a work in progress. I make it for my own use to make my job easier. Some features I've implemented are in a "good enough" state. I use GitHub issues to manage my task list. If you find a deficiency, add an issue.

Once this gem is in 1.0, I will push an actual gem. Things I want in place before I go to 1.0 are:

  • Support for sorting via Ransack
  • Support for searching via Ransack
  • Support for has_many associations
  • Support for has_and_belongs_to_many associations

Important Caveat: Pairing with Rails Template

This gem is specifically made to be paired with the Frontier Template. Technology choices in these generators are completely dependent on what is in the latest version of Frontier Template.

If you want to use this gem in another rails project, you'd need to rewrite some of the output of the generators.

When I use these generators in other rails projects I only enable the model and seeds generators.

Installing

Add the following to the development group in your Gemfile:

gem 'frontier_generators', github: "thefrontiergroup/frontier_generators"

Basic Usage

You can create a YAML specification of your entities that you can pass directly to any of the generators. EG:

rails g frontier_scaffold /path/to/yml

Model Options

You can define a model with some options as follows:

model_name:
  # Use CanCanCan instead of Pundit (`pundit` by default)
  authorization: cancancan
  # Do not generate factory. `false` by default.
  skip_factory: true
  # Do not generate model. `false` by default.
  skip_model: true
  # Do not generate policies. `false` by default.
  skip_policies: true
  # Do not generate a blank seed rake task for this model. `false` by default.
  skip_seeds: true
  # Do not create controller, routes, views, or specs for the above. `false` by default.
  skip_ui: true
  # Or skip specific controllers, views and specs
  skip_ui: [create, index, update, delete]
  # Adds support to soft delete for this model (acts_as_paranoid). `true` by default
  soft_delete: true

Namespaces and nested routes

You can specify a set of namespaces or a collection of models that your generated controller will be nested under using the controller_prefixes option.

NOTE: Support for nested resources is a WIP.

Missing features:

  • routes
model_name:
  # Example: A single namespace
  #
  # Controller: Admin::ModelNamesController
  # Route:      admin_model_names_path (admin/model_names)
  # Views:      views/admin/model_names
  controller_prefixes: ['admin']

  # Example: A single nested resource
  #
  # Controller: Client::ModelNamesController
  # Route:      client_model_names_path(@client) (client/:id/model_names)
  # Views:      views/client/model_names
  controller_prefixes: [@client]

  # Example: A namespace and a nested resource
  #
  # Controller: Admin::Client::ModelNamesController
  # Route:      admin_client_model_names_path(@client) (admin/client/:id/model_names)
  # Views:      views/admin/client/model_names
  controller_prefixes: ['admin', @client]

Attributes

You can specify which attributes should be on your model thusly:

model_name:
  attributes:
    attribute_name:
      # Set primary to true if you want this attribute to be used for #to_s and for
      # checks in the feature specs. Chooses first attribute by default.
      primary: true
      # Set to false if you don't want this attribute to be represented on the index
      # Note: This is true by default
      show_on_index: false
      # Set to false to prevent this attribute being used in the form
      # Note: this is true by default
      show_on_form: false
      # Add in support for sorting on this attribute using Ransack.
      sortable: true

      # Choose one of the following
      type: boolean
      type: datetime
      type: date
      type: decimal
      type: integer
      type: string
      type: text

      # enum should also provide enum_options
      type: enum
      enum_options: ['admin', 'public']

NOTE: Support for the sortable attribute is partially implemented. It is currently missing implementation for nested resources.

Associations

You can add validations the same way you would add an attribute. Currently supported:

EG:

model_name:
  attributes:
    attribute_name:
      # Optional - this will use this model in factories and in the model
      class_name: "User"
      # One of inline or select
      form_type: "inline"
      attributes:
        # This should be a collection similar to the above. Show all the attributes and their type that you want to show in the inline form
      type: "belongs_to"

Validations

You can add validations to your models. This will provide implementations and specs when generated.

Frontier currently supports the following validations:

model_name:
  attributes:
    attribute_name:
      validates:
        inclusion: [1,2,3,4]
        length:
          minimum: 0
          maximum: 666
          is: 100
          # in and within are aliases for eachother
          in: 0..100
          within: 0..100
        numericality: true
        # Or, numericality can use one or more args
        numericality:
          allow_nil: true
          greater_than: 0
          greater_than_or_equal_to: 0
          equal_to: 0
          less_than: 100
          less_than_or_equal_to: 100
          only_integer: true
        presence: true
        uniqueness: true
        # Or, uniquenss can support the scope argument
        uniqueness:
          scope: user_id

Views

By default, FG will generate views that fit with the look and feel of the Rails Template.

You can override the view templates that are used to generate the index, new, edit, and form pages by specifying a path to these templates:

model_name:
  view_paths:
    index: "config/frontier_generators/views/index.html.haml"
    new: "config/frontier_generators/views/new.html.haml"
    edit: "config/frontier_generators/views/edit.html.haml"
    form: "config/frontier_generators/views/form.html.haml"

You should look at how these templates are generated by FG to get an idea of how you can override them.

frontier_generators's People

Contributors

osiro avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

jordanmaguire

frontier_generators's Issues

extra comma on belongs_to association

The following yaml:

address:
  attributes:
    line_1:
      type: "string"
      validates:
        presence: true
    line_2:
      type: "string"
    suburb:
      type: "string"
      validates:
        presence: true
    postal_code:
      type: "string"
      validates:
        presence: true
    state:
      type: "belongs_to"
      validates:
        presence: true

Generated:

class Address < ActiveRecord::Base
  # Soft delete - uses deleted_at field
  acts_as_paranoid

  belongs_to :state,

  validates :line_1, presence: true
  validates :suburb, presence: true
  validates :postal_code, presence: true
  validates :state, presence: true

  def to_s
    line_1
  end

end

Didn't have enough time to look into that, but I think it's something to do in here: https://github.com/thefrontiergroup/frontier_generators/blob/master/lib/model_configuration/association.rb#L40

BTW, in newer versions of Rails, we do not need to do validates :state, presence: true, we can pretty much do belongs_to :state, required: true.

Thought about changing the generators to validates associations with require true.

Form generation for associations is broken.

interview_questionnaire:
  namespaces: ["member"]
  skip_seeds: true
  attributes:
    address:
      show_on_index: false
      type: belongs_to

generates..

= simple_form_for [:member, @interview_questionnaire], wrapper: "horizontal", html: {class: "form-horizontal"} do |f|
  = f.association :address_id, collection: Address.all
  .form-actions
    = f.button :submit
    %span.or or
    = link_to "Cancel", member_interview_questionnaires_path

instead of

= simple_form_for [:member, @interview_questionnaire], wrapper: "horizontal", html: {class: "form-horizontal"} do |f|
  = f.association :address, collection: Address.all
  .form-actions
    = f.button :submit
    %span.or or
    = link_to "Cancel", member_interview_questionnaires_path

Move shared example block out into shared group

  shared_examples_for "Policy without access to CRUD actions" do
    it { should_not permit_access_to(:index) }
    it { should_not permit_access_to(:new) }
    it { should_not permit_access_to(:create) }
    it { should_not permit_access_to(:edit) }
    it { should_not permit_access_to(:update) }
    it { should_not permit_access_to(:destroy) }
  end

Migrations for attributes with different class names are broken

interview_questionnaire:
  namespaces: ["member"]
  skip_seeds: true
  attributes:
    gp_address:
      show_on_index: false
      type: belongs_to
      class_name: "Address"

will generate the following migration

class CreateInterviewQuestionnaire < ActiveRecord::Migration
  def change
    create_table :interview_questionnaires do |t|
      t.belongs_to :gp_address, index: true, foreign_key: true
      t.datetime :created_at
      t.datetime :updated_at
      t.datetime :deleted_at
    end
    add_index :interview_questionnaires, :deleted_at
  end
end

This will fail PGError: ERROR: relation “gp_address” does not exist. The migration requires a 'references' component, which you can't use foreign_key: true on :/. Migration should end up looking like this for it to work.

class CreateInterviewQuestionnaire < ActiveRecord::Migration
  def change
    create_table :interview_questionnaires do |t|
      t.belongs_to :gp_address, references: :addresses, index: true
      t.datetime :created_at
      t.datetime :updated_at
      t.datetime :deleted_at
    end
    add_index :interview_questionnaires, :deleted_at
    add_foreign_key :interview_questionnaires, :addresses, column: :gp_address_id
  end
end

Generate sidebar link for menu options

It's time to make this map pretty hard to the rails template so that we can save more time.

Add option include_sidebar_link that defaults to true to support this implementation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.