Skip to content

Instantly share code, notes, and snippets.

@Slike9
Last active July 12, 2023 00:15
Show Gist options
  • Save Slike9/d8b7280c4cb48f11568b to your computer and use it in GitHub Desktop.
Save Slike9/d8b7280c4cb48f11568b to your computer and use it in GitHub Desktop.
rails ModelForm
module ModelForm
extend ActiveSupport::Concern
included do
class_attribute :model_class
self.model_class = self.superclass
end
module ClassMethods
def model_name
model_class.model_name
end
def permit(*permitted_attrs)
@permitted_attrs = permitted_attrs
end
def permitted_attrs
@permitted_attrs
end
def wrap(model)
model.becomes(self).tap do |form|
form.model = model
end
end
end
def assign_attributes(attrs = {})
if attrs.respond_to?(:permitted?)
attrs = attrs.permit(*self.class.permitted_attrs)
end
super(attrs)
end
def model
@model ||= self.becomes(self.class.model_class)
end
def model=(value)
@model = value
end
end
@Slike9
Copy link
Author

Slike9 commented Apr 22, 2015

Usage:

app/models/post.rb

  class Post < ActiveRecord::Base
  end

app/forms/post_form.rb

  class PostForm < Post
    include ModelForm

    validates :text, presence: true

    permit :name, :text
  end

app/controllers/posts_controller.rb

class PostsController < ApplicationController
  def new
    @post_form = PostForm.new
  end

  def create
    @post_form = PostForm.new(params[:post])

    if @post_form.save
      redirect_to @post_form.model
    else
      render :new
    end
  end

  def edit
    @post_form = PostForm.wrap(post)
  end

  def update
    @post_form = PostForm.wrap(post)

    if @post_form.update(params[:post])
      redirect_to @post_form.model
    else
      render :edit
    end
  end

  private

  def post
    @post ||= Post.find(params[:id])
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment