Coder Social home page Coder Social logo

reform's Introduction

Reform

Gitter Chat TRB Newsletter Build Status Gem Version

Form objects decoupled from your models.

Reform gives you a form object with validations and nested setup of models. It is completely framework-agnostic and doesn't care about your database.

Although reform can be used in any Ruby framework, it comes with Rails support, works with simple_form and other form gems, allows nesting forms to implement has_one and has_many relationships, can compose a form from multiple objects and gives you coercion.

Full Documentation

Reform is part of the Trailblazer framework. Full documentation is available on the project site.

Reform 2.2

Temporary note: Reform 2.2 does not automatically load Rails files anymore (e.g. ActiveModel::Validations). You need the reform-rails gem, see Installation.

Defining Forms

Forms are defined in separate classes. Often, these classes partially map to a model.

class AlbumForm < Reform::Form
  property :title
  validates :title, presence: true
end

Fields are declared using ::property. Validations work exactly as you know it from Rails or other frameworks. Note that validations no longer go into the model.

The API

Forms have a ridiculously simple API with only a handful of public methods.

  1. #initialize always requires a model that the form represents.
  2. #validate(params) updates the form's fields with the input data (only the form, not the model) and then runs all validations. The return value is the boolean result of the validations.
  3. #errors returns validation messages in a classic ActiveModel style.
  4. #sync writes form data back to the model. This will only use setter methods on the model(s).
  5. #save (optional) will call #save on the model and nested models. Note that this implies a #sync call.
  6. #prepopulate! (optional) will run pre-population hooks to "fill out" your form before rendering.

In addition to the main API, forms expose accessors to the defined properties. This is used for rendering or manual operations.

Setup

In your controller or operation you create a form instance and pass in the models you want to work on.

class AlbumsController
  def new
    @form = AlbumForm.new(Album.new)
  end

This will also work as an editing form with an existing album.

def edit
  @form = AlbumForm.new(Album.find(1))
end

Reform will read property values from the model in setup. In our example, the AlbumForm will call album.title to populate the title field.

Rendering Forms

Your @form is now ready to be rendered, either do it yourself or use something like Rails' #form_for, simple_form or formtastic.

= form_for @form do |f|
  = f.input :title

Nested forms and collections can be easily rendered with fields_for, etc. Note that you no longer pass the model to the form builder, but the Reform instance.

Optionally, you might want to use the #prepopulate! method to pre-populate fields and prepare the form for rendering.

Validation

After form submission, you need to validate the input.

class SongsController
  def create
    @form = SongForm.new(Song.new)

    #=> params: {song: {title: "Rio", length: "366"}}

    if @form.validate(params[:song])

The #validate method first updates the values of the form - the underlying model is still treated as immutuable and remains unchanged. It then runs all validations you provided in the form.

It's the only entry point for updating the form. This is per design, as separating writing and validation doesn't make sense for a form.

This allows rendering the form after validate with the data that has been submitted. However, don't get confused, the model's values are still the old, original values and are only changed after a #save or #sync operation.

Syncing Back

After validation, you have two choices: either call #save and let Reform sort out the rest. Or call #sync, which will write all the properties back to the model. In a nested form, this works recursively, of course.

It's then up to you what to do with the updated models - they're still unsaved.

Saving Forms

The easiest way to save the data is to call #save on the form.

if @form.validate(params[:song])
  @form.save  #=> populates album with incoming data
              #   by calling @form.album.title=.
else
  # handle validation errors.
end

This will sync the data to the model and then call album.save.

Sometimes, you need to do saving manually.

Default values

Reform allows default values to be provided for properties.

class AlbumForm < Reform::Form
  property :price_in_cents, default: 9_95
end

Saving Forms Manually

Calling #save with a block will provide a nested hash of the form's properties and values. This does not call #save on the models and allows you to implement the saving yourself.

The block parameter is a nested hash of the form input.

  @form.save do |hash|
    hash      #=> {title: "Greatest Hits"}
    Album.create(hash)
  end

You can always access the form's model. This is helpful when you were using populators to set up objects when validating.

  @form.save do |hash|
    album = @form.model

    album.update_attributes(hash[:album])
  end

Nesting

Reform provides support for nested objects. Let's say the Album model keeps some associations.

class Album < ActiveRecord::Base
  has_one  :artist
  has_many :songs
end

The implementation details do not really matter here, as long as your album exposes readers and writes like Album#artist and Album#songs, this allows you to define nested forms.

class AlbumForm < Reform::Form
  property :title
  validates :title, presence: true

  property :artist do
    property :full_name
    validates :full_name, presence: true
  end

  collection :songs do
    property :name
  end
end

You can also reuse an existing form from elsewhere using :form.

property :artist, form: ArtistForm

Nested Setup

Reform will wrap defined nested objects in their own forms. This happens automatically when instantiating the form.

album.songs #=> [<Song name:"Run To The Hills">]

form = AlbumForm.new(album)
form.songs[0] #=> <SongForm model: <Song name:"Run To The Hills">>
form.songs[0].name #=> "Run To The Hills"

Nested Rendering

When rendering a nested form you can use the form's readers to access the nested forms.

= text_field :title,         @form.title
= text_field "artist[name]", @form.artist.name

Or use something like #fields_for in a Rails environment.

= form_for @form do |f|
  = f.text_field :title

  = f.fields_for :artist do |a|
    = a.text_field :name

Nested Processing

validate will assign values to the nested forms. sync and save work analogue to the non-nested form, just in a recursive way.

The block form of #save would give you the following data.

@form.save do |nested|
  nested #=> {title:  "Greatest Hits",
         #    artist: {name: "Duran Duran"},
         #    songs: [{title: "Hungry Like The Wolf"},
         #            {title: "Last Chance On The Stairways"}]
         #   }
  end

The manual saving with block is not encouraged. You should rather check the Disposable docs to find out how to implement your manual tweak with the official API.

Populating Forms

Very often, you need to give Reform some information how to create or find nested objects when validateing. This directive is called populator and documented here.

Installation

Add this line to your Gemfile:

gem "reform"

Reform works fine with Rails 3.1-5.0. However, inheritance of validations with ActiveModel::Validations is broken in Rails 3.2 and 4.0.

Since Reform 2.2, you have to add the reform-rails gem to your Gemfile to automatically load ActiveModel/Rails files.

gem "reform-rails"

Since Reform 2.0 you need to specify which validation backend you want to use (unless you're in a Rails environment where ActiveModel will be used).

To use ActiveModel (not recommended because very out-dated).

require "reform/form/active_model/validations"
Reform::Form.class_eval do
  include Reform::Form::ActiveModel::Validations
end

To use dry-validation (recommended).

require "reform/form/dry"
Reform::Form.class_eval do
  feature Reform::Form::Dry
end

Put this in an initializer or on top of your script.

Compositions

Reform allows to map multiple models to one form. The complete documentation is here, however, this is how it works.

class AlbumForm < Reform::Form
  include Composition

  property :id,    on: :album
  property :title, on: :album
  property :songs, on: :cd
  property :cd_id, on: :cd, from: :id
end

When initializing a composition, you have to pass a hash that contains the composees.

AlbumForm.new(album: album, cd: CD.find(1))

More

Reform comes many more optional features, like hash fields, coercion, virtual fields, and so on. Check the full documentation here.

Reform is part of the Trailblazer project. Please buy my book to support the development and learn everything about Reform - there's two chapters dedicated to Reform!

Security And Strong_parameters

By explicitly defining the form layout using ::property there is no more need for protecting from unwanted input. strong_parameter or attr_accessible become obsolete. Reform will simply ignore undefined incoming parameters.

This is not Reform 1.x!

Temporary note: This is the README and API for Reform 2. On the public API, only a few tiny things have changed. Here are the Reform 1.2 docs.

Anyway, please upgrade and report problems and do not simply assume that we will magically find out what needs to get fixed. When in trouble, join us on Gitter.

Full documentation for Reform is available online, or support us and grab the Trailblazer book. There is an Upgrading Guide to help you migrate through versions.

Attributions!!!

Great thanks to Blake Education for giving us the freedom and time to develop this project in 2013 while working on their project.

reform's People

Contributors

apotonick avatar arturictus avatar azdaroth avatar bdewater avatar blelump avatar cameron-martin avatar emaglio avatar fernandes avatar fran-worley avatar francirp avatar freemanoid avatar gdott9 avatar gogogarrett avatar jdwolk avatar levinalex avatar lime avatar lukeasrodgers avatar mattheworiordan avatar mjonuschat avatar myabc avatar pabloh avatar parndt avatar richardboehme avatar seuros avatar simoniong avatar slashek avatar tevanoff avatar timoschilling avatar twonegatives avatar yogeshjain999 avatar

Stargazers

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

Watchers

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

reform's Issues

undefined method `to_key` for a <put a Reform::Form class here>

I recognize that this can be easily avoided by adding a to_key method as written in your example here: https://github.com/gogogarrett/reform_example/blob/master/app/forms/forms/artist_form.rb

... but why should it be?

Here's a rough sample of my form (w/ to_key):

class ReservationForm < Reform::Form
  include DSL
  properties [:first_name, :last_name], on: :visitor
  properties [:credit_card_number, :credit_card_cvv], on: :billing

  def to_key
    [1]
  end
end

Uniqueness validation doesn't work when using composition

First of all thanks for creating this gem - good work!

I'm having problems trying to use the uniqueness validation for a Reform form object. It works fine when the form represents a single model (e.g. User) but does not work when using composition (i.e. when the form represents multiple models). I'm using Rails 4.0.0 and Ruby 2.0.0p-247.

When the validate method is called on the form object I get an error like:

NoMethodError: undefined method `read_attribute_for_validation' for #<#<Class:0x007fb56c8fbfa0>:0x007fb56ea0dc48>

The following works fine:

class UserForm < Reform::Form
  include Reform::Form::ActiveRecord

  property :email

  validates :email, presence: true, uniqueness: true
end

The following does not:

class UserForm < Reform::Form
  include Reform::Form::ActiveRecord
  include Reform::Form::Composition

  model :user

  property :email,            on: :user
  property :name,             on: :profile
  property :date_of_birth,    on: :profile
  property :favorite_color,   on: :profile

  validates :email, presence: true, uniqueness: true
end

Here's a test:

require 'test_helper'

class UserFormTest < ActiveSupport::TestCase

  setup do
    @user = User.new
    @profile = UserProfile.new
    @form = UserForm.new(user: @user, profile: @profile)
  end

  def valid_params
    params = {'email'=>'[email protected]', 'name'=>'Bobert', 'date_of_birth'=>'Tue, 22 Oct 2000', 'favorite_color'=>'Green'}
  end

  test "fails validation if email blank" do
    params = valid_params.merge('email'=>'')
    refute @form.validate(params)
  end

  test "passes validation if all good" do
    assert @form.validate(valid_params)
  end

  test "requires email to be unique" do
    u = User.create!(email: '[email protected]')
    refute @form.validate(valid_params)
    assert @form.errors[:email].any?
  end

end

Running the tests gives errors:

# Running tests:

EEE

Finished tests in 0.084186s, 35.6354 tests/s, 0.0000 assertions/s.

  1) Error:
UserFormTest#test_fails_validation_if_email_blank:
NoMethodError: undefined method `read_attribute_for_validation' for #<#<Class:0x007fb56c8fbfa0>:0x007fb56c93b088>
    test/forms/user_form_test.rb:17:in `block in <class:UserFormTest>'

  2) Error:
UserFormTest#test_passes_validation_if_all_good:
NoMethodError: undefined method `read_attribute_for_validation' for #<#<Class:0x007fb56c8fbfa0>:0x007fb56e992840>
    test/forms/user_form_test.rb:21:in `block in <class:UserFormTest>'

  3) Error:
UserFormTest#test_requires_email_to_be_unique:
NoMethodError: undefined method `read_attribute_for_validation' for #<#<Class:0x007fb56c8fbfa0>:0x007fb56ea0dc48>
    test/forms/user_form_test.rb:26:in `block in <class:UserFormTest>'

Here lines 17, 21, 26 here refer to the lines in the tests where @form.validate(...) is called.

Thanks.

Rename `on:` to `key:`

I find on to be a very unclear word to describe what the property method achieves.

Take the following example:

property :email,        on: :user
properties [:gender, :age],   on: :profile

model :user 

On first glance, it looks as if the property email is defined on the user model. It's not immediately obvious that the on specifies the key in the params hash.

It gets even more hazy when you start reading:

model :singer, :on => :user

I propose the alternative. You could support on for backward compatibility

property :email,        key: :user
properties [:gender, :age],   key: :profile

model :user 

and

model :singer, :key => :user

If you like it, I'll start making the necessary changes.

Why is :on needed to access form.[model] ?

I really liked the (https://github.com/gogogarrett/reform_example)[example] @gogogarrett made, with separate form workflows. Wanted to replicate this but for a simpler case, only one model. Had some issues, I'll try to explain.

This is how it works:

class Users::UserProfilesController < ApplicationController
  ...
  def create_edit_form
    @form = Users::UserProfileForm.new(user: user)
  end
end

class Users::UserProfileForm < Reform::Form
  include DSL

  model :user, on: :user

  property :email, on: :user
  property :name, on: :user
end

class Users::UserProfileWorkflow
  ...
  def process
    ...
    form.save do |data, map|
      if form.user.new_record?
    ...
  end
end

So the idea is to pass in the form to workflow where it can further delegate saving to a service. The problematic part is form.user. Only with the above combination is it possible to get the user object from the form to check whether it is a new object or not.

So, this is what confuses me:

  • DSL in form, it is deprecated, but without it this doesn't work
  • in main readme usually only the plain model is passed to form when initialized, but here we have to use .new(user: user), I suppose this is because of the above included DSL
  • due to DSL, the on: :user is needed for all properties

I guess the question is can we relay on DSL, being deprecated?

Bumping version please

@apotonick great gem, rolling out extensively, but I recently hit the inheritance issue #53 locally. After trawling through everything, I realise that whilst I am using the latest version 0.2.4, it does not include the fixes to enable inheritance.

Can you bump the version so that I don't have to lock my Gemfile into a commit?

Thanks.

Feature request: write form values back to the model but don't call model#save

Reform already does this with any property that has validations. I would love for it to also do this with any other [non-virtual] properties I declare.

My reason for this is simple: sometimes I have to do some additional custom processing before I #save the model โ€“ so I can't just use Form#save w/o a block. But because I already do my validations inside of Reform, I don't use strong parameters, and that means inside of the Form#save block I either have to initialize a new model instance and pass it all of the params (not great if there are virtual/empty params being used) OR re-use reform.model and set everything by hand.

So this is what I envision:

# person_form.rb
class PersonForm < Reform::Form
  property :name
  property :description

  validates :name, presence: true
end

User submits the form and all validations pass. Meanwhile, in the controller:

# person_controller.rb
class PersonController
  def process_form
    #assume @form was initialized somewhere else with either a Person.new instance (e.g. on New) OR an existing Person from the DB (e.g. on Edit)
    # This is a standard use case w/ things like decent_exposure
    if @form.validate(params[:person])
        @form.save do |form, data|
            Rails.logger.info @form.model.name           # => "Arthur" (Reform already does this today, because there was a validator on :name)
            Rails.logger.info @form.model.description     # => "Cool guy" (Feature request)

            @form.model.name.upcase!        # My custom manipulation

            @form.model.save!                      # now I can save things happily.
         end
    end
  end
end

Avoiding duplication of validates method

I have a model with validation and form with validation. Why I duplicate some validation methods from model to form? It isn't dry!

Is there any ways to avoid this bad behaviour?

Reform::Form::ActiveRecord is not automatically included?

The Readme says:

Reform provides the following ActiveRecord specific features. They're mixed in automatically in a Rails/AR setup.
Calling Form#save will explicitely call save on your model (added in 0.2.1) which will usually trigger a database insertion or update.

But it seems like you still have to manually include Reform::Form::ActiveRecord into your model in order to have those features (auto-saving).

Maybe that is the intended behavior, but if so, the Readme should be updated to say that you must include that module rather than "They're mixed in automatically".

Looking at https://github.com/apotonick/reform/blob/master/lib/reform/rails.rb, it looks like Reform::Form::ActiveModel and Reform::Form::ActiveModel::FormBuilderMethods are automatically mixed in, but (even though reform/form/active_record is required), Reform::Form::ActiveRecord is not.

undefined method `model' for

Here is my form

class PersonalForm < Reform::Form
  include DSL
  include Reform::Form::ActiveRecord

  properties [:birhtdate, :email, :hour_rate, :location, :name, :site, :skype, :speciality, :status], on: :profile

  model :user, on: :user
end

When I trying to initialize form I gets undefined method `model' for error. Whats wrong?

Using Reform for a search form

I tried to use reform as a form object for a search form, but in order to use reform I had to initialise it by passing an object to the constructor.

Is it possible to create a reform object with no parameters?

Nested form issue: undefined method from_hash for nil

I haven't slept much, so probably I'm missing something obvious but I've been going around this for a couple hours to no avail.

class InvoiceForm < Reform::Form
  include Reform::Form::ActiveRecord

  property :date

  collection :line_items do
    property :description
    property :quantity
    property :price
  end
end

params = {"date"=>"2014-02-18", "line_items_attributes"=>
{"1392781994276"=>{"_destroy"=>"false", "description"=>"Manual entry", "quantity"=>"1", "price"=>"20"}}}

invoice = InvoiceForm.new(Invoice.new)
invoice.validate(params) # This throws the error on lib/representable/deserializer.rb:50

Right now I'm about to use a composition instead, to work around this issue, but I'm wondering what's the real problem.

Rails 4 - is it ready?

I'm asking because I'd like to use the gem in a new Rails 4 project.

My first attempts are unsuccessful - I'm getting an "undefined method `persisted?'" error...

Issue with date field being blank

I have a date field in a a form and I check that the date is present.
When I submit the form I get a validation error saying that the date can't be blank.
Is it due to the way date fields are sent ?

app/controllers/legal_details_controller.rb

class LegalDetailsController < ApplicationController
  expose(:legal_details_form) do
    LegalDetailsForm.new(current_user)
  end

  def update
    if legal_details_form.validate(params[:legal_details])
      # ...
    end
  end
end

app/forms/legal_details_form.rb

class LegalDetailsForm < Reform::Form
  include Reform::Form::ActiveRecord

  properties %i[birthdate]

  model :legal_details

  validates :birthdate,
    presence: true
end

app/views/legal_details/edit.html.slim

= simple_form_for legal_details_form, url: legal_details_path do |f|
  = f.input :birthdate, as: :date
  = f.button :button

params

"legal_details" => {
  "birthdate(3i)" => "1",
  "birthdate(2i)" => "1",
  "birthdate(1i)" => "2013"
}

How to handle when Form property does not map to a model

how can I do this ? dont really want to pollute data model with accessors

the data model does not have password or password_confirmation but I want to validate at the form level and I dont want to populate the data model with these properties either; cant see any easy way; kind of get lost around the representer class etc.

the simplest way would be if I can just set a property but without an :on option. that would be really nice; it validates() but does not populate the model

thanks

require 'reform/form/coercion'

module RegistrationApp
  class RegistrationForm <  Reform::Form
    include DSL
    include Reform::Form::ActiveModel
    include Reform::Form::Coercion

    #ย model
    model :user

    property :email, on: :user, type: ::RegistrationApp::Virtus::StringDowncaseStrip
    property :password, on: :user
    property :password_confirmation, on: :user

    #ย valdiations
    validates :password, presence: true, confirmation: true, :length => { :in => 4..20 }, :allow_nil => true
    validates :email, presence: true, format: {with: RFC822::EMAIL}, :allow_nil => true

  end
end

I18n error translations for nested models aren't scoped properly

Consider the following:

class Employee < ActiveRecord::Base
  belongs_to :user
end
class User < ActiveRecord::Base
   has_one :employee
end
class EmployeeForm < Reform::Form
  include Reform::Form::ActiveRecord

  property :user do
    property :email
    validates :email, presence: true
  end
end

When I submitted my form w/ an empty email, I could not figure out what key ActiveModel was trying to use to get the 'errors' translations, so I monkey-patched it to spit it out the args to the log file. Here is what I found:

(Each line represents the *args of a single call to I18n.translate)

[:"activemodel.errors.models.anon_inline.attributes.email.blank", {:default=>[:"activemodel.errors.models.anon_inline.blank", :"activemodel.errors.models.reform/.attributes.email.blank", :"activemodel.errors.models.reform/.blank", :"activemodel.errors.messages.blank", :"errors.attributes.email.blank", :"errors.messages.blank"], :model=>"Anon inline", :attribute=>"Email", :value=>""}]
[:"activemodel.errors.models.anon_inline.blank", {:model=>"Anon inline", :attribute=>"Email", :value=>"", :locale=>:en, :throw=>true}]
[:"activemodel.errors.models.reform/.attributes.email.blank", {:model=>"Anon inline", :attribute=>"Email", :value=>"", :locale=>:en, :throw=>true}]
[:"activemodel.errors.models.reform/.blank", {:model=>"Anon inline", :attribute=>"Email", :value=>"", :locale=>:en, :throw=>true}]
[:"activemodel.errors.messages.blank", {:model=>"Anon inline", :attribute=>"Email", :value=>"", :locale=>:en, :throw=>true}]

Obvious workaround is just to pass the message to the validates call (or doing the translation myself), but this is tedious. Thanks for taking a look.

Ability to access and manipulate values inside of form object

When I am working inside of the form object that inherits from Reform::Form, is there any way to access the submitted values? Additionally is there a way to create a before_validation callback to manipulate form values. I am familiar with doing this in models but I was unable to get access to the form field values inside of the form object.

Updating @model after save

I'm finding I need to do this:

@record.save do |form, attributes|
  record = Record.new(attributes)
  record.user = current_user
  record.save!
  form.model = record # Should this be automatic?
end

So that I can use redirect_to with @record. I understand how Reform wants to know as little as possible about the persistence layer, but this is handy:

@record.save do |form, attributes|
  form.model = Record.new(attributes).tap do |record|
    record.user = current_user
    record.save!
  end
end

And I'm actually pushing that code to the form (with the proper adjustments), and the controller just calls @record.create(params[:record]). Hopefully this isn't too out of reform's philosophy? Or is there a better way?

Here's the full code when pushed to the form:

def create(params)
  return false unless validate(params)

  save do |form, attributes|
    form.model = Record.new(attributes).tap do |record|
      record.user = model.user
      record.save!
    end
  end

  true
end

Should I leave that to the controller? I kind of like how simple the actions end up being...

Just looking for some feedback while I'm getting used to this nifty gem :)

How to handle has_many relations?

I'm not sure whether if it is already supported and is missing docs or if it doesn't work yet but it would be pretty cool if we could handle one to many associations :-)

Attributes are not filled on a composed form

Hello,

I have a simple form like this:

class CollectorRegistrationForm < Reform::Form
  include Composition

  properties [:profile, :email, :password, :password_confirmation,
              :remember_me, :name, :phone, :confirmed_at, :confirmation_token,
              :confirmation_sent_at, :first_name, :sex, :current_password],
              on: :user

  properties [:address, :postal_code, :city, :country, :country_id, :region,
              :region_id], on: :profile


  validates :postal_code, :city, :country, :name, :first_name, :sex, :phone,
    presence: true
end

When I do this:

profile = CollectorProfile.first
user = profile.user
form = CollectorRegistrationForm.new(user: user, profile: profile)
form.validate(first_name: nil) # return true
form.user.first_name # return the user's name (not nil)
user.first_name = nil
form = CollectorRegistrationForm.new(user: user, profile: profile)
form.validate(first_name: "test") # return false

Reform seems to not take the attributes in the validation's hash. Is there something I don't understand?

Thanks!

Multiple level of nesting

I'm trying to handle a deep nested structure in a form - I realise that maybe I shouldn't be:-). However, this is part of wizard and it simplifies the code to allow this deep nesting.
Although the price bands are being passed in the params they are not getting populated in the form (the form has an empty array).

Am I making some simple mistake or is the problem with Reform?

thanks

jon

class Product < ActiveRecord::Base
  has_one :pricing_model, dependent: :destroy
end

class PricingModel < ActiveRecord::Base
  belongs_to :product
  has_many :price_bands, dependent: :destroy
end

class PriceBand < ActiveRecord::Base
  belongs_to :pricing_model
end

class PricingForm < Reform::Form
  include Reform::Form::ActiveModel
  include Reform::Form::ActiveModel::FormBuilderMethods

  model :product

  property :pricing_model do
    property :pricing_strategy_id
    property :base_price

    collection :price_bands do
      property :phase
      property :start_value
     end
  end
end

    Parameters: {"utf8"=>"โœ“", "authenticity_token"=>"mvRdAn/0Kjka/TJ7kYgINzUxVzwQUN6DBrz0RxpANtE=", "product"=>{"pricing_model_attributes"=>{"pricing_strategy_id"=>"1", "base_price"=>"24", "variable_price"=>"43", "variable_name"=>"number_in_roll", "quoted_product_details"=>"", "price_bands_attributes"=>{"0"=>{"phase"=>"1", "start_value"=>"23", "end_value"=>"43", "_destroy"=>"false"}}, "id"=>"133"}}, "commit"=>"Next", "product_id"=>"147", "id"=>"pricing"}


#<ProductWizard::PricingForm:0xb576c68
 @errors=
  #<Reform::Form::Errors:0xb2f4990
   @base=#<ProductWizard::PricingForm:0xb576c68 ...>,
   @messages={}>,
 @fields=
  #<Reform::Fields pricing_model=#<#<Class:0xb2f7d70>:0xbca5cdc @model=#<PricingModel id: 133, product_id: 147, pricing_strategy_id: 1, base_price: 24, variable_name: "number_in_roll", variable_price: 43, manual_price: nil, quoted_product_details: "", apply_discount: nil, discount_start_date: nil, discount_end_date: nil, discount_type: nil, discount_minimum_order_quantity: nil, discount_calculation: nil, discount_amount: nil, invoicing_basis: nil, invoicing_rule: nil, created_at: "2014-02-15 16:48:44", updated_at: "2014-02-15 17:11:51">, @fields=#<Reform::Fields pricing_strategy_id="1", base_price="24", quoted_product_details="", variable_name="number_in_roll", variable_price="43", price_bands=[]>, @errors=#<Reform::Form::Errors:0xb2f4544 @base=#<#<Class:0xb2f7d70>:0xbca5cdc ...>, @messages={}>, @validation_context=nil>>,
 @model=
  #<Product id: 147, type: "Product", parent_id: 108, service_parent_id: nil, product_parent_id: nil, classification_id: nil, name: "Product #2", customer_type: "ABC", service_year_id: nil, subscription_period: "All", sku: 10147, short_description: "", long_description: nil, core: nil, built: false, created_at: "2014-02-15 16:48:44", updated_at: "2014-02-15 16:48:54">,
 @validation_context=nil>


Using collections when there are no items

if I create a form object (lets say for a user) and use the collection method (such that a user can have multiple permissions) then this will fail if the there are no items for the form's collection.

Basically it fails here if there are no permissions for the user form object:
params[attr.name] = params["#{attr.name}_attributes"].values
(Line 26 of reform (0.2.1) lib/reform/form/active_model.rb)

Because params["#{attr.name}_attributes"] will not exist rather than being an empty hash table.

collection seems to be assuming a 1..many relationship when really has_many in AR assumes a 0..many relationship

Need Support for Form inheritance

Hi.
Here is it an example:

  class UserForm <  Reform::Form
    propery :name
    # more fields ,more logic
  end
  class CustomerForm < UserForm
    property :address
  end

the fields of CustomerForm will not contain UserForm's fields.
because of @representer_class is a class instance variable

Inherit model validation?

Hi,

Does reform inherit the validation from the model for the fields associated with it, or do you have to re-add the validation you want?

Domain Validations Stay in Model?

just a thought: I am not 100 on this as an idea; but ideas are cool; I really like reforms approach on the form object arena.

in terms of validations; especially when it comes to uniqueness etc; the model should deal with those validations and not the form object? the form should only validate at the form level? no more require active_record mongoid variants on validates unique etc. so the form object still has validations but just ones that it can handle.

if model has been set on the form object then prehaps the validate and save can by default delegate down to the model itself; but you can opt out.

validate will have merged error messages from the model object; via calling valid? on the model; not sure I like that as the model will need populating hmmm

save will not only populate incoming data but will also call model.save ;again optional and if block given then most def dont call save on the model

in theory we can by default have

if form.validate({"email" => "[email protected]"}) && form.save
  # blar
end

Cheers

Using empty fields on composition objects

Attempting to use an empty field such as property :password_confirmation, :empty => true causes an error when including Composition.

To reproduce

clone https://github.com/grossadamm/ReformEmptyWithComposition

or

setup the project

rails new emptytest/

add reform to Gemfile

bundle
rails g model song title:string
rails g model label city:string
rake db:migrate
mkdir app/forms
mkdir test/forms

add these files

app/forms/empty_with_composition.rb

  class EmptyWithComposition < Reform::Form
    include Composition
    property :title, on: :song
    property :city,  on: :label
    property :empty_thing, :empty => true
  end

test/forms/empty_with_composition_test.rb

  require 'test_helper'

  class EmptyWithCompositionTest < ActiveSupport::TestCase

    test "should be ok with empty thing" do 
        form = EmptyWithComposition.new(song: Song.new, label: Label.new)
        validation = form.validate(
            "title" => "my title",
            "city" => "my cool city",
            "empty_thing" => "empty"
      )
        assert validation
    end
  end

run the test

rake test test/forms/empty_with_composition_test.rb

see error

   Run options: --seed 708

   # Running tests:

   E

   Finished tests in 0.035624s, 28.0708 tests/s, 0.0000 assertions/s.

     1) Error:
   EmptyWithCompositionTest#test_should_be_ok_with_empty_thing:
   SyntaxError: /home/agross/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/forwardable.rb:169: syntax error, unexpected *
         def (*args, &block)
               ^
   /home/agross/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/forwardable.rb:169: syntax error, unexpected &
         def (*args, &block)
                      ^
       app/forms/empty_with_composition.rb:5:in `<class:EmptyWithComposition>'
       app/forms/empty_with_composition.rb:1:in `<top (required)>'
       test/forms/empty_with_composition_test.rb:6:in `block in <class:EmptyWithCompositionTest>'

   1 tests, 0 assertions, 0 failures, 1 errors, 0 skips

Collection inside of nested property throws an error

Hi folks!

By the time of writing this issue, it is already classified as a bug and is getting fixed.
I just wanna to let you know about it.

The model situation is described below.
Let's have a form class like this:

class DocumentForm < Reform::Form
...
  property :a do
    collection :b do
    ...
    end
  end
...
end

Then, when creating the form object with provided models' object...

DocumentForm.new(@document)

...is everything ok, but only if the provided models' object has defined both the :a and :b.

But (this is the issue), if :a is nil and thus the :b is nil too, the reform is trying to assign the :b anyway, but can't because the outer :a is nil.

Have a nice day! :-)

undefined method `superclass' for Reform::Form::DSL:Module

I ran into this error after I updated the reform gem in this reform_example app and went to /users/new.

The error was:

undefined method `superclass' for Reform::Form::DSL:Module

I don't know how to fix it. Seems to have to do with the inheritable_attr :model_options bit.

uber (0.0.4) lib/uber/inheritable_attr.rb:16:in `inherit_for'
(eval):7:in `model_options'
bundler/gems/reform-830ed9deed9d/lib/reform/form/active_model.rb:78:in `model_name'
activemodel (4.0.0.rc1) lib/active_model/translation.rb:57:in `block in human_attribute_name'
activemodel (4.0.0.rc1) lib/active_model/translation.rb:56:in `map'
activemodel (4.0.0.rc1) lib/active_model/translation.rb:56:in `human_attribute_name'
actionpack (4.0.0.rc1) lib/action_view/helpers/tags/label.rb:54:in `render'
actionpack (4.0.0.rc1) lib/action_view/helpers/form_helper.rb:750:in `label'
actionpack (4.0.0.rc1) lib/action_view/helpers/form_helper.rb:1589:in `label'
app/views/users/_form.html.erb:3:in `block in _app_views_users__form_html_erb___232801701415194634_20247200'

Here's the relevant code from lib/reform/form/active_model.rb:

    def model_name
      if model_options
        form_name = model_options.first.to_s.camelize
      else
        form_name = name.sub(/Form$/, "")
      end

      active_model_name_for(form_name)
    end

  module ClassMethods
    # this module is only meant to extend (not include). # DISCUSS: is this a sustainable concept?
    def self.extended(base)
      base.class_eval do
        extend Uber::InheritableAttribute
        inheritable_attr :model_options
      end
    end

exception raised when nested property is nil

The following code for me is triggering a big stacktrace with error NoMethodError: undefined method name' for nil:NilClass`

class Album < OpenStruct
end

class AlbumForm < Reform::Form
  property :artist do
    property :name
  end
end

AlbumForm.new(Album.new)

One way around this is to override the #initialize and ensure that the nested property (model.artist) exists, but I think that might be too brittle. I have a couple of ideas on how to possibly fix this:

  1. #initialize could call a new prepare_model method which subclasses of Reform::Form could override. Not a great deal better than overriding #initialize though.

  2. property method could support a :builder option that takes a block, or symbol containing a method name to invoke on the model (i.e. :build_artist in a has_one/belongs_to ActiveRecord relationship).

What are your thoughts?

Question about form#save behavior with Rails

I'm experimenting with Reform, and really like parts of it so far. However, I'm a bit confused about the role of form.save as intended.

Ideally, I would like for it to map the form data to the provided objects and allow me to access those objects. So for example:

form = SongForm.new(Song.new)
form.validate(params)
form.save
form.song  # I thought it would returns the song object populated with params data, but object is not saved to the database.

However, when I try this in practice, calling form.song raises an error. Additionally, I see a note in the README that the function might (as of v0.2.1) call a database save. How do I go about accessing the model with assigned attributes from the form object?

I18n scope problem

Hello, I'm a rails beginner, below is the code in my form class

errors.add(:nickname, :empty);

after form.validate(params[:xxx]), i output the errors.full_messages

the column name not read the i18n namespace activerecord correctly

the reason is Reform::Form class i18n_scope is :activemodel

2.0.0p247 :025 > HsrTicketForm.i18n_scope
 => :activemodel

I found out a solution, add the following code in my form class

class << self
    def i18n_scope
      :activerecord
    end
  end 

but i have to add this code in all of my form class, any better solutions? thanks.

Virtual Attributes for Compositions

Hi, I saw reform support Virtual Attributes now, a really helpful feature,but it seems not working with compositions, I tried to make it work, since I'm not good at writting test, and not known reform's code structure very well, please help me review what I'm done,
niedhui@4b15ec1 thanks

Problem using forms outside controllers?

I have the following code that I am trying to use in my seeds.rb file when running bundle exec rake db:seed but it's not working. Whatever I run my seeds it's failing saying everything is nil and it is

# CODE USING REFORM
username = `whoami`.chomp
params = {
  username: username,
  email: "#{username}@example.com",
  birthdate: Date.new(1978, 07, 19),
  password: 'Abc123',
  password_confirmation: 'Abc123',
  first_name: 'User',
  last_name: 'Name',
  street: 'Black Jack Street 25',
  zip: '352 63',
  city: 'Game City',
  country: 'Free Spins',
  gender: 'Male'
}

require 'reform/rails'
begin
  form = PlayerForm.new(player: Player.new, address: Address.new)
  registration = PlayerWorkflow.new(form, params)
  registration.process
rescue => e
  p e.message, e.backtrace; Rails.logger.error { e }
end
pp form.errors
#<ActiveModel::Errors:0x007fe99d931898
 @base=
  #<Reform::Fields avatar=nil, birthdate=nil, username=nil, email=nil, password=nil, password_confirmation=nil, first_name=nil, last_name=nil, gender=nil, street=nil, zip=nil, city=nil, country=nil, mobile=nil>,
 @messages=
  {:birthdate=>["can't be blank", "is not a valid date"],
   :username=>["can't be blank"],
   :email=>["can't be blank", "is invalid"]}>
=> #<ActiveModel::Errors:0x007fe99d931898 @base=#<Reform::Fields avatar=nil, birthdate=nil, username=nil, email=nil, password=nil, password_confirmation=nil, first_name=nil, last_name=nil, gender=nil, street=nil, zip=nil, city=nil, country=nil, mobile=nil>, @messages={:birthdate=>["can't be blank", "is not a valid date"], :username=>["can't be blank"], :email=>["can't be blank", "is invalid"]}>

However when using that form with the exact same data from RSpec or browser it works fine. What is up with that?

How to get the validate result without validate again

I have a multi row form for update data

def set_session_forms(sessions)
      session_forms = []
      sessions.each do |session|
        session_forms.push({model: session, form: ActivitySessionForm.new(session)})
      end
      session_forms
end
<%= simple_form_for :sessions %>
  <% @session_forms.each do |session| %>
    <%= simple_fields_for "sessions[#{session[:form].id}]", session[:form] do |f| %>
     ....
    <% end %>
  <% end %>
<% end %>

i put reform to a array and run validate in loop, if any one validate is false, then render the view to display the error rows. i need a validate result cache like below

<%= simple_fields_for "sessions[#{session[:form].id}]", session[:form] do |f| %>
  <tr>
    <% if session[:form].is_valid? # from cache %> 
      ... error things
    <% end %>
  </tr>
<% end %>

other one thing, i use sessions[:form], because when i valid the params pass, i need to get the model to save, so i have to store the model to other place, any idea can use forms to get model in this version 2.0.0

i think it must have requirement to get model from reform, or other solution to access the activerecord dirty attrs

@session_form = SessionForm.new Session.new
@session_form.model.new_record?

I am a rails beginner, i don't know what is the better solution, if i am wrong please let me know. thanks.

One to many: undefined method `from_hash' for nil:NilClass on validate

Validate seems to run fine if I have no nested models. But if I have a has_many relation with a appropriate collection call in the form I get the above error.

My form code:

class ProjectForm < Reform::Form
  model      :project, on: :project

  properties [:name, :number_of_buildings, :number_of_parking_slots], on: :project

  validates :name,
            presence:     true
  validates :number_of_buildings,
            presence:     true
  validates :number_of_parking_slots,
            presence:     true

  collection :buildings do
    model    :building, on: :building

    properties [:name, :number_of_floors, :number_of_apartments], on: :building

    validates :name,
              presence:     true
    validates :number_of_floors
              presence:     true
    validates :number_of_apartments,
              presence:     true
  end
end

And of course, a Project has_many Buildings. I am using Reform 0.2.0.

Am I doing something I am not supposed to, or did I stumble on a bug?

Rails has_one and *_attributes params

Hi,

I'm trying to use reform to provide a form for users to modify their profile.
The profile form uses the user itself (a Student here) and can also modify the account email attribute.

I'm using the code that follows but the generated form uses student[account_attributes][email] instead of student[account][email].
I know it's expected from Rails but my form object is not so fond of it...

I get an error saying

undefined method `has_key?' for nil:NilClass
# in Representable::Hash::PropertyBinding#read

because at some point it tries to access params['student']['account'] and it returns nil.

Is it supposed to work out of the box and I'm missing something or is it something I'm supposed to work around ?

Thanks

# app/models/user.rb
class Student < ActiveRecord::Base
  has_one :account,
    as: :user,
    inverse_of: :user
end

# app/models/account.rb
class Account < ActiveRecord::Base
    belongs_to :user,
      inverse_of: :account,
      polymorphic: true,
      touch: true
end

# app/forms/student_profile_form.rb
class StudentProfileForm < Reform::Form
  include Reform::Form::ActiveRecord

  property :account do
    property :email
  end

  properties :firstname, :gender, :lastname, :phone_number

  model :profile
end

# app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
  def edit
    @profile_form = StudentProfileForm.new(current_student)
  end

  def update
    @profile_form = StudentProfileForm.new(current_student)
    if @profile_form.validate(params) && @profile_form.save
      redirect_to profile_path
    else
      render action: 'edit'
    end
  end
end
/ app/views/profiles/edit.html.slim
= simple_form_for @profile_form do |f|
  = f.input :firstname
  / ...
  = f.fields_for :account do |a|
    = a.input :email

validates_uniqueness_of doesn't work with inline nested forms

class EmployeeForm < Reform::Form
  include Reform::Form::ActiveRecord

  property :user do
    property :email

    validates :email, presence: true
    validates_uniqueness_of :email
  end
end

Results in:

NoMethodError - undefined method `validates_uniqueness_of' for #<Class:0x007fc3c4e4bf08>:

I understand that validates_uniqueness_of comes from Reform::Form::ActiveRecord, so I tried including that in the nested form, like so:

class EmployeeForm < Reform::Form
  include Reform::Form::ActiveRecord

  property :user do
    include Reform::Form::ActiveRecord # <-- Trying to get uniqueness validator into here
    property :email

    validates :email, presence: true
    validates_uniqueness_of :email
  end
end

But that results in:

NoMethodError - undefined method `has_key?' for nil:NilClass:

So, now I'm stuck. I know this might work with v0.2.2's explicit form: UserForm, but I can't do that because of the issue I mentioned here: #47 (comment)

A simple solution would be to pass on all of the stuff in Reform::Form::ActiveRecord to nested forms.

Use form class on property definition doesn't create the #<property>_attributes= method

Hi guys,

The new option to define a nested property passing a form object as option is awesome, the only problem that i found was that when you specify a property this way, your 'master' form doesn't create the #<property>_attributes= method necessary to render the form with simple_form or form helpers.

Here are examples of both cases and the output of a console test showing that the method is not defined:

class AddressForm < Reform::Form
  property :receiver do
    property :name
  end
  #property :receiver, form: ReceiverForm
end

screen shot 2013-12-12 at 10 05 18

class AddressForm < Reform::Form
  #property :receiver do
   # property :name
  #end
  property :receiver, form: ReceiverForm
end

screen shot 2013-12-12 at 10 07 16

Property aliasing doesn't work

I'll illustrate with a code example:

company = Company.new(name: 'Foo')

class CompanyForm < Reform::Form
  property :name, as: :title
end

form = CompanyForm.new(company)

form.title # => NoMethodError: undefined method `title'
form.name # => nil
form.send :fields # => #<Reform::Fields name=nil, title="Foo">

I'm using version 0.2.4.

Access to model(s) in getter

My particular use-case involves the rolify gem (https://github.com/EppO/rolify). I'm trying to create a virtual property on the form based on whether the user has a certain role on a certain resource. This is a simplified version:

# Form
class UserForm < Reform::Form
  include Reform::Form::ActiveRecord

  model :user

  def initialize(user, forum)
    super(user)
    @forum = forum
  end

  def user
    model
  end

  property :name
  property :is_admin, virtual: true, getter: lambda do |data|
    user.has_role?(:admin, @forum)
  end
end

I would then save the form with a save block:

# part of controller update method
...
@form.save do |data, nested|
  @form.user.name = data.name
  @form.user.save!

  if data.is_admin == '1'
    @form.user.add_role(:admin, @forum)
  else
    @form.user.remove_role(:admin, @forum)
  end
end
...

This is a specific example, but I imagine a main use case for getters would be to create virtual properties that combine instance information from the model with information outside of the model (if you just need information from a single model instance I think defining a method on the model with the same name as the form property will work with virtual: true without needing a getter?).

Is there currently any way to accomplish what I'm trying to do? The getter lambda does not seem to have access to any instance methods or properties on the form. It seems to get executed in the models context? I'm also not sure if the object that gets passed as an argument to the getter lambda could be of any help. As far as I can tell it's an Option object, which is basically a hash and it's empty?

I might be missing something obvious, I'm not yet that familiar with ruby. I was hoping someone here could point me in the right direction.

Issue with validations in Rails 4

Hi,

I'm trying to make the following form object work in a Rails 4 application.

require 'reform/rails'

class StudentDetailsForm < Reform::Form
  include DSL
  include Reform::Form::ActiveRecord

  property :firstname, on: :student

  model :student

  validates :firstname, presence: true
end

I'm having a hard time with validations:

f = StudentDetailsForm.new(student: Student.new)
#=> #<Reform::Fields firstname=nil>

f.validate(firstname: 'x')
#=> false

f.errors.full_messages
#=> ["Firstname can't be blank"]

It's a Rails 4 application but I don't know if it's related. Any idea what's wrong here?

Undefined method for an ActiveRecord model

Hi,

I try to do a very simple thing. I have this form :

require 'reform/rails'

class OrderForm < Reform::Form
  include DSL
  include Reform::Form::ActiveRecord

  model :order, on: :order
end

I have this in my controller :

def new
  @form = OrderForm.new(order: Order.new)
end

And this in my view :

<%= simple_form_for(@form) do |f| %>
<% end %>

Very simple but I have this error :

undefined method `order' for #<#<Class:0x007fb2de576780>:0x007fb2dd6f3f28>

I tried to change my controller for this :

def new
  @form = OrderForm.new(order: Order.new)
  @form.order
end

And It's the same thing.

I tried with the master branch and the version '0.1.2'.

Did I missing something?

Thanks for you help and good job @apotonick!

Coercion doesn't work inside collections

It seems the virtus coersions don't work inside collections - e.g:

class SomeForm < Reform::Form
  include Coercion

  property :birthday, type: Date

  collection :someobjects do
    property :somebool, type: Boolean
  end
end    

This fails with

uninitialized constant ProjectForm::Boolean

Strangely, it doesn't seem to affect all object types - String for example doesn't throw an error...

Using nested objects doesn't populate decedent items/models. (Plus saving strategies)

If I do something like

class TagForm < Reform::Form
  property :category
  property :primary_label do
    property :name
  end
  collection :aliased_labels do
    property :name
  end
end

test = TagForm.new Tag.new.tap &:build_primary_label
stuff = { "category" => "classification", "primary_label_attributes" => { "name" => "Rumor" }, "aliased_labels_attributes" => [ { "name" => "Market Talk" }, { "name" => "Speculation" } ] }
test.validate stuff

I get the following results. I'm not sure if this is "by design" / intentional or not. To me it just seems a little inconsistent and maybe a bit baffling as a new user

test.model.primary_label.name # nil
test.primary_label.model.name # nil
test.primary_label.name # "Rumor"

I would have expected all 3 to produce "Rumor", rather than a first two end up with nil. Especially given that test.model has all it's attributes set, it seems odd that items within nested properties do not set these details (I would have thought it would have been possible to do this lazily when you access test.primary_label.model - I'm not too sure what you'd do in the case of test.model.primary_label as this might be a trickier case to deal with.

Even if this "by design" I wonder if this is worth documenting along with the reasons/motivations?

The original reason I bring this up is also is that I'd like to come up with a generic way to be able to save objects when dealing with nesting, in the same way that accepts_nested_attributes_for is able to. My guess is that 80% of the time users will want to mimic accepts_nested_attributes_for as for the most part this is normally what is needed, and it's just a handful of times where a more fine control is needed (maybe a good idea to create some sort of "save policy" system to handle the bulk of generic cases when saving nested models). For the most part accepts_nested_attributes_for does the job for me apart from a few cases when it comes to deal with error handling (because errors in nested model objects shouldn't be handled by the top most / active / original callee model object.

On this note I think would would be handy would be a way to have some sort of utility method that returns child model objects from the nesting process in some sort of collection so it would be easy to iterate over and save them. I guess the other issue at hand here is how we deal with assigning foreign keys, such as making sure that tag_id is assigned when saving the labels. (Obviously this would need to support several layers / levels of nesting)

Plus for a large part, reform for me and I guess for a number of other users is seems to be more about having an alternative to StrongParams (which in my mind is an ugly solution), along with the ability to break down models / decorate models with specific validations/logic for specific contexts.

I did skim over the source and notice you have a model.save call as a default action when saving and have placed a comment to state that you plan to deal with case of dealing with nested model objects.

error: undefined method `persisted?'

on rails 4 with Composition included I have to specify

  model :birnen, on: :birnen

otherwise I get an error: undefined method persisted?'` Not sure if this is an bug or just need to be better documentation, maybe a hint at the composition section.

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.