Permalink
Browse files

Added tests, forms and form support for Def Entries

  • Loading branch information...
1 parent 93c96ad commit 2dac70ab085e82b1ddf5e18904e5b09118a1632c Guy Boertje committed May 26, 2009
View
30 README
@@ -1,6 +1,10 @@
HasFlexibleFields
=================
+Added: Forms for Flexifield Definition management. Uses nested forms.
+Added: Wrapped Columns for Flexifield Definition Entry, wraps ActiveRecord::ConnectionAdapters::<Adapter>Column in a
+Struct to provide a content attribute and two convenience methods to use in view or form creation
+
The problem:
How does one add fields to a model (usually another project's models) without permanently altering the model structure?
@@ -40,8 +44,8 @@ NOTE: remember the polymorphic nature of the flexifield model, only drop the ff
TODO:
-partials for flexifield definitions forms
-
+DONE: partials for flexifield definitions forms
+DONE: partials for flexifield data entry
NOTE: currently this version requires rails v 2.3.2
@@ -62,26 +66,30 @@ and flexifield_def_entries of:
ffd1e1:
flexifield_def_id: 1
flexifield_name: ffs_01
- flexifield_alias: preparation time
- ordering: 1
+ flexifield_alias: preparation_time
+ flexifield_tooltip: Enter time in decimal hours or minutes
+ flexifield_order: 1
ffd1e2:
flexifield_def_id: 1
flexifield_name: ffs_02
- flexifield_alias: cooking time
- ordering: 2
+ flexifield_alias: cooking_time
+ flexifield_tooltip: Enter time in H hours M minutes
+ flexifield_order: 2
Then this saves the additional content with the main content...
r = Content.create! :title => 'Roast Pork Belly', :body => 'Ingredients: ...'
- r.assign_ff_def 1
- r.assign_ff_value 'preparation time', '25 minutes'
- r.assign_ff_value 'cooking time', '2 hours 30 minutes'
+ r.ff_def= 1
+ r.set_ff_value 'preparation_time', '25 minutes'
+ r.set_ff_value 'cooking_time', '2 hours 30 minutes'
+ r.assign_ff_values {:preparation_time => '25 minutes', :cooking_time => '2 hours 30 minutes'}
+ r.get_ff_value(:preparation_time) # -> '25 minutes'
and
- r.ff_aliases # -> ["preparation time","cooking time"]
+ r.ff_aliases # -> ["preparation_time","cooking_time"]
r.ff_fields # -> ["ffs_01","ffs_02"]
and
r.to_ff_alias 'ffs_01' # -> "preparation time"
- r.to_ff_field 'cooking time' # -> "ffs_02"
+ r.to_ff_field 'cooking_time' # -> "ffs_02"
But forms that save to ffs_NN directly will also work.
@@ -0,0 +1,93 @@
+class FlexifieldDefEntriesController < ApplicationController
+
+ before_filter :get_flexifield_def
+ before_filter :find_flexifield_def_entry, :only => %w(show update destroy)
+
+ layout 'flexifield_defs'
+
+ # GET /flexifield_defs/:flexifield_def_id/flexifield_def_entries
+ # GET /flexifield_defs/:flexifield_def_id/flexifield_def_entries.xml
+ def index
+ @flexifield_def_entries = @flexifield_def.flexifield_def_entries.find(:all)
+ respond_to do |format|
+ format.html # index.html.erb
+ format.xml { render :xml => @flexifield_def_entries }
+ end
+ end
+
+ # GET /flexifield_defs/:flexifield_def_id/flexifield_def_entries/1
+ # GET /flexifield_defs/:flexifield_def_id/flexifield_def_entries/1.xml
+ def show
+ respond_to do |format|
+ format.html # show.html.erb
+ format.xml { render :xml => @flexifield_def_entry }
+ end
+ end
+
+ # GET /flexifield_defs/:flexifield_def_id/flexifield_def_entries/new
+ # GET /flexifield_defs/:flexifield_def_id/flexifield_def_entries/new.xml
+ def new
+ @flexifield_def_entry = @flexifield_def.flexifield_def_entries.new
+ respond_to do |format|
+ format.html # new.html.erb
+ format.xml { render :xml => @flexifield_def_entry }
+ end
+ end
+
+ # GET /flexifield_defs/:flexifield_def_id/flexifield_def_entries/1/edit
+ def edit
+ end
+
+ # POST /flexifield_defs/:flexifield_def_id/flexifield_def_entries
+ # POST /flexifield_defs/:flexifield_def_id/flexifield_def_entries.xml
+ def create
+ @flexifield_def_entry = @flexifield_def.flexifield_def_entries.new(params[:flexifield_def_entry])
+ respond_to do |format|
+ if @flexifield_def_entry.save
+ flash[:notice] = 'FlexifieldDefEntry was successfully created.'
+ format.html { redirect_to(@flexifield_def_entry) }
+ format.xml { render :xml => @flexifield_def_entry, :status => :created, :location => @flexifield_def_entry }
+ else
+ format.html { render :action => "new" }
+ format.xml { render :xml => @flexifield_def_entry.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # PUT /flexifield_defs/:flexifield_def_id/flexifield_def_entries/1
+ # PUT /flexifield_defs/:flexifield_def_id/flexifield_def_entries/1.xml
+ def update
+ respond_to do |format|
+ if @flexifield_def_entry.update_attributes(params[:flexifield_def_entry])
+ flash[:notice] = 'FlexifieldDefEntry was successfully updated.'
+ format.html { redirect_to(@flexifield_def_entry) }
+ format.xml { head :ok }
+ else
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @flexifield_def_entry.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /flexifield_defs/:flexifield_def_id/flexifield_def_entries/1
+ # DELETE /flexifield_defs/:flexifield_def_id/flexifield_def_entries/1.xml
+ def destroy
+ @flexifield_def_entry.destroy
+ respond_to do |format|
+ format.html { redirect_to(flexifield_def_entries_url) }
+ format.xml { head :ok }
+ end
+ end
+
+ private
+
+ def find_flexifield_def_entry
+ get_flexifield_def unless @flexifield_def
+ @flexifield_def_entry = @flexifield_def.flexifield_def_entries.find(params[:id])
+ end
+
+ def get_flexifield_def
+ @flexifield_def = FlexifieldDef.find(params[:flexifield_def_id])
+ end
+
+end
@@ -0,0 +1,103 @@
+class FlexifieldDefsController < ApplicationController
+
+ before_filter :find_flexifield_def, :only => %w(show edit update destroy)
+
+ helper_method :setup_flexifield_def
+
+ # GET /flexifield_defs
+ # GET /flexifield_defs.xml
+ def index
+ @flexifield_defs = FlexifieldDef.all :include => :flexifield_def_entries
+
+ respond_to do |format|
+ format.html # index.html.erb
+ format.xml { render :xml => @flexifield_defs }
+ end
+ end
+
+ # GET /flexifield_defs/1
+ # GET /flexifield_defs/1.xml
+ def show
+ @flexifield_def = FlexifieldDef.find(params[:id], :include => :flexifield_def_entries)
+
+ respond_to do |format|
+ format.html # show.html.erb
+ format.xml { render :xml => @flexifield_def }
+ end
+ end
+
+ # GET /flexifield_defs/new
+ # GET /flexifield_defs/new.xml
+ def new
+ @flexifield_def = FlexifieldDef.new
+
+ respond_to do |format|
+ format.html # new.html.erb
+ format.xml { render :xml => @flexifield_def }
+ end
+ end
+
+ # GET /flexifield_defs/1/edit
+ def edit
+ end
+
+ # POST /flexifield_defs
+ # POST /flexifield_defs.xml
+ def create
+ @flexifield_def = FlexifieldDef.new(params[:flexifield_def])
+
+ respond_to do |format|
+ if @flexifield_def.save
+ flash[:notice] = 'FlexifieldDef was successfully created.'
+ format.html { redirect_to(@flexifield_def) } #flexifield_defs_url
+ format.xml { render :xml => @flexifield_def, :status => :created, :location => @flexifield_def }
+ else
+ format.html { render :action => "new" }
+ format.xml { render :xml => @flexifield_def.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # PUT /flexifield_defs/1
+ # PUT /flexifield_defs/1.xml
+ def update
+ respond_to do |format|
+ if @flexifield_def.update_attributes(params[:flexifield_def])
+ flash[:notice] = 'FlexifieldDef was successfully updated.'
+ format.html { redirect_to(@flexifield_def) }
+ format.xml { head :ok }
+ else
+ format.html { render :action => "edit" }
+ format.xml { render :xml => @flexifield_def.errors, :status => :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /flexifield_defs/1
+ # DELETE /flexifield_defs/1.xml
+ def destroy
+ @flexifield_def.destroy
+
+ respond_to do |format|
+ format.html { redirect_to(flexifield_defs_url) }
+ format.xml { head :ok }
+ end
+ end
+
+ def setup_flexifield_def(flexifield_def)
+ returning(flexifield_def) do |ffd|
+ if ffd.flexifield_def_entries.empty?
+ ffd.flexifield_def_entries.build
+ end
+ if !ffd.flexifield_def_entries.last.id.blank? && ffd.flexifield_def_entries.length < Flexifield.flexiblefield_names_count
+ ffd.flexifield_def_entries << FlexifieldDefEntry.new()
+ end
+ end
+ end
+
+ private
+
+ def find_flexifield_def
+ @flexifield_def = FlexifieldDef.find(params[:id], :include => :flexifield_def_entries)
+ end
+end
View
@@ -0,0 +1,57 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+
+class Flexifield < ActiveRecord::Base
+
+ belongs_to :flexifield_set, :polymorphic => true
+ belongs_to :flexifield_def, :include => 'flexifield_def_entries'
+
+ delegate :to_ff_alias, :to_ff_field, :ff_aliases, :ff_fields, :to => :flexifield_def
+
+ def self.flexiblefield_names
+ columns.map(&:name).grep(/ff.+_/)
+ end
+
+ def self.flexiblefield_names_count
+ columns.map(&:name).grep(/ff.+_/).length
+ end
+
+ def ff_def
+ read_attribute :flexifield_def_id
+ end
+
+ def ff_def= ff_def_id
+ write_attribute :flexifield_def_id, ff_def_id
+ save
+ end
+
+ def get_ff_value ff_alias
+ ff_field = to_ff_field ff_alias
+ if ff_field
+ read_attribute ff_field
+ else
+ raise ArgumentError, "Flexifield alias: #{ff_alias} not found in flexifeld def mapping"
+ end
+ end
+
+ def set_ff_value ff_alias, ff_value
+ ff_field = to_ff_field ff_alias
+ if ff_field
+ write_attribute ff_field, ff_value
+ else
+ raise ArgumentError, "Flexifield alias: #{ff_alias} not found in flexifeld def mapping"
+ end
+ end
+
+ def assign_ff_values args_hash
+ unless args_hash.is_a? Hash
+ raise ArgumentError, "Method argument must be a hash"
+ end
+ args_hash.each do |ffalias, ffvalue|
+ set_ff_value ffalias, ffvalue
+ end
+ save
+ end
+
+
+end
@@ -1,20 +1,27 @@
class FlexifieldDef < ActiveRecord::Base
- has_many :flexifield_def_entries, :class_name => 'FlexifieldDefEntry', :order => 'ordering', :dependent => :destroy
- accepts_nested_attributes_for :flexifield_def_entries
+ has_many :flexifield_def_entries, :class_name => 'FlexifieldDefEntry', :order => 'flexifield_order', :dependent => :destroy
+ accepts_nested_attributes_for :flexifield_def_entries,
+ :reject_if => proc { |attrs| attrs['flexifield_alias'].blank? }
+ validates_presence_of :name
+
+ #after_update :save_entries
+
def to_ff_field ff_alias
idx = nil
+ ffa = "#{ff_alias}"
ff_aliases.each_with_index do |c,i|
- idx = i if c == ff_alias
+ idx = i if c == ffa
end
idx ? flexifield_def_entries[idx].to_ff_field : nil
end
def to_ff_alias ff_field
idx = nil
+ fff = "#{ff_field}" #make sure it is a string
ff_fields.each_with_index do |c,i|
- idx = i if c == ff_field
+ idx = i if c == fff
end
idx ? flexifield_def_entries[idx].to_ff_alias : nil
end
@@ -27,5 +34,15 @@ def ff_fields
flexifield_def_entries.nil? ? [] : flexifield_def_entries.map(&:flexifield_name)
end
+ def unassigned_flexifield_names
+ Flexifield.flexiblefield_names - ff_fields
+ end
+
+ private
+ def save_entries
+ flexifield_def_entries.each do |entry|
+ entry.save false
+ end
+ end
end
Oops, something went wrong.

0 comments on commit 2dac70a

Please sign in to comment.