Skip to content

Instantly share code, notes, and snippets.

@gregory
Created November 17, 2012 00:30
Show Gist options
  • Save gregory/4092178 to your computer and use it in GitHub Desktop.
Save gregory/4092178 to your computer and use it in GitHub Desktop.
fields_for :profile_or_build
module Extensions
module ActiveRecord
module BuildForHasOne
module InstanceMethods
def self.included(base)
base.send :alias_method_chain, :method_missing, :build
end
private
def method_missing_with_build(method, *args, &block)
relation_name = method.to_s.scan(/(\w+)_or_build$/).flatten.first
return method_missing_without_build(method, *args, &block) unless relation_name.present? && respond_to?(relation_name.to_sym)
reflection = self.class.reflect_on_association(relation_name.to_sym)
unless reflection.collection?
self.class_eval do
name = reflection.name
define_method method do
return send(name) || send(:"build_#{name}")
end
end
send(method)
end
end
end
end
end
end
ActiveRecord::Base.send :include, Extensions::ActiveRecord::BuildForHasOne::InstanceMethods
module Extensions
module ActionView
module Helpers
module FormBuilder
def self.included(klass)
klass.class_eval do
def fields_for_with_association(record_name, record_object = nil, fields_options = {}, &block)
if record_object.is_a?(Hash) && record_object.has_key?(:build_if_empty)
fields_options, record_object = record_object, nil
fields_options.delete(:build_if_empty)
association_name = record_name.is_a?(Array) ? ActiveModel::Naming.param_key(record_name.last) : record_name
record_object = @object.send("#{association_name}_or_build") unless record_object
end
fields_for_without_association(record_name, record_object, fields_options, &block)
end
alias_method_chain :fields_for, :association
end
end
end
end
end
end
ActionView::Helpers::FormBuilder.send :include, Extensions::ActionView::Helpers::FormBuilder if defined?(ActionView)
<%= f.fields_for :profile_or_build, {build_if_empty: true} do |profile|%>
<%= profile.label :name %>
<%= profile.text_field :name %>
<% end %>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment