Skip to content

Instantly share code, notes, and snippets.

@joshmn
Created April 12, 2023 22:29
Show Gist options
  • Save joshmn/39eb6f302650e09743387710591abb2d to your computer and use it in GitHub Desktop.
Save joshmn/39eb6f302650e09743387710591abb2d to your computer and use it in GitHub Desktop.
<!-- posts/_form.html.erb -->
<%= simple_form_for @form do |f| %>
<%= f.input :user_id %>
<%= f.input :subject %>
<%= f.input :content %>
<%= f.submit %>
<% end %>
class ApplicationForm
include ActiveModel::Model
include ActiveModel::Attributes
attr_reader :context
attribute :id, :integer
def self.from_params(params)
new.tap do |form|
params.each do |k,v|
if form.attributes.include?(k)
form.public_send("#{k}=", v)
end
end
end
end
def self.from_model(model)
new.tap { |form| form.map_model(model) }
end
# self.user_id = model.user_id
# self.title = model.title
def map_model(model)
raise ArgumentError, "not defined."
end
def self.model_name
ActiveModel::Name.new(self, nil, form_name.to_s.camelize)
end
def self.acts_like(val)
@acts_like = val
end
def self.form_name
@acts_like || inferred_name
end
def self.inferred_name
self.name.demodulize.underscore.to_sym
end
def persisted?
id.present? && id.to_i > 0
end
def to_key
[id]
end
def to_model
self
end
def to_param
id.to_s
end
def attributes
super.except(:id)
end
end
# forms/posts/new_form.rb
module Posts
class NewForm < ApplicationForm
acts_like :post
attribute :user_id, :integer
attribute :subject, :string
attribute :content, :string
validates :user_id, presence: true
end
end
class PostsController < ApplicationController
def new
@form = Posts::NewForm.new
end
def create
@form = Posts::NewForm.from_params(post_params)
unless @form.valid?
render :new
end
end
private
def post_params
params.require(:post).permit(:subject, :user_id, :content)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment