Skip to content

Commit

Permalink
Adding a new feature: display_with. It provides direct support for us…
Browse files Browse the repository at this point in the history
…e a view helper to render an attribute
  • Loading branch information
Roger Campos committed Dec 24, 2011
1 parent 1ebf06a commit e7f132d
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 11 deletions.
4 changes: 4 additions & 0 deletions lib/best_in_place.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@

module BestInPlace
autoload :TestHelpers, "best_in_place/test_helpers"

module ViewHelpers
extend ActionView::Helpers
end
end
7 changes: 2 additions & 5 deletions lib/best_in_place/controller_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ def respond_bip_ok(obj)
klass = obj.class.to_s
updating_attr = params[klass.underscore].keys.first

if renderer = BestInPlace::DisplayMethods.lookup(klass, updating_attr)
render :json => {:display_as => obj.send(renderer)}.to_json
else
head :ok
end
renderer = BestInPlace::DisplayMethods.lookup(klass, updating_attr)
render :json => renderer.render_json(obj)
end

def respond_bip_error(obj)
Expand Down
23 changes: 20 additions & 3 deletions lib/best_in_place/display_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,32 @@ module BestInPlace
module DisplayMethods
extend self

class Renderer < Struct.new(:opts)
def render_json(object)
case opts[:type]
when :model
{:display_as => object.send(opts[:method])}.to_json
when :helper
{:display_as => BestInPlace::ViewHelpers.send(opts[:method], object.send(opts[:attr]))}.to_json
else
{}.to_json
end
end
end

@@table = Hash.new { |h,k| h[k] = Hash.new(&h.default_proc) }

def lookup(klass, attr)
foo = @@table[klass.to_s][attr.to_s]
foo == {} ? nil : foo
foo == {} ? Renderer.new : foo
end

def add_model_method(klass, attr, display_as)
@@table[klass.to_s][attr.to_s] = Renderer.new :method => display_as.to_sym, :type => :model
end

def add(klass, attr, display_as)
@@table[klass.to_s][attr.to_s] = display_as.to_sym
def add_helper_method(klass, attr, helper_method)
@@table[klass.to_s][attr.to_s] = Renderer.new :method => helper_method.to_sym, :type => :helper, :attr => attr
end
end
end
17 changes: 15 additions & 2 deletions lib/best_in_place/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ module BestInPlace
module BestInPlaceHelpers

def best_in_place(object, field, opts = {})
if opts[:display_as] && opts[:display_with]
raise ArgumentError, "Can't use both 'display_as' and 'display_with' options at the same time"
end

if opts[:display_with] && !ViewHelpers.respond_to?(opts[:display_with])
raise ArgumentError, "Can't find helper #{opts[:display_with]}"
end

opts[:type] ||= :input
opts[:collection] ||= []
field = field.to_s
Expand Down Expand Up @@ -33,7 +41,7 @@ def best_in_place(object, field, opts = {})
out << " data-type='#{opts[:type]}'"
out << " data-inner-class='#{opts[:inner_class]}'" if opts[:inner_class]
out << " data-html-attrs='#{opts[:html_attrs].to_json}'" unless opts[:html_attrs].blank?
out << " data-original-content='#{object.send(field)}'" if opts[:display_as]
out << " data-original-content='#{object.send(field)}'" if opts[:display_as] || opts[:display_with]
if !opts[:sanitize].nil? && !opts[:sanitize]
out << " data-sanitize='false'>"
out << sanitize(value, :tags => %w(b i u s a strong em p h1 h2 h3 h4 h5 ul li ol hr pre span img br), :attributes => %w(id class href))
Expand All @@ -55,8 +63,13 @@ def best_in_place_if(condition, object, field, opts={})
private
def build_value_for(object, field, opts)
if opts[:display_as]
BestInPlace::DisplayMethods.add(object.class.to_s, field, opts[:display_as])
BestInPlace::DisplayMethods.add_model_method(object.class.to_s, field, opts[:display_as])
object.send(opts[:display_as]).to_s

elsif opts[:display_with]
BestInPlace::DisplayMethods.add_helper_method(object.class.to_s, field, opts[:display_with])
BestInPlace::ViewHelpers.send(opts[:display_with], object.send(field))

else
object.send(field).to_s.presence || ""
end
Expand Down
7 changes: 7 additions & 0 deletions test_app/app/views/users/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@
<td id="description">
<%= best_in_place @user, :description, :display_as => :markdown_desc, :type => :textarea, :sanitize => false %>
</td>
</tr>
<tr>
<td>Money</td>
<td id="money">
<%= best_in_place @user, :money, :display_with => :number_to_currency %>
</td>
</tr>
</table>
<br />
<hr />
Expand Down
5 changes: 5 additions & 0 deletions test_app/db/migrate/20111224181356_add_money_to_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddMoneyToUser < ActiveRecord::Migration
def change
add_column :users, :money, :float
end
end
3 changes: 2 additions & 1 deletion test_app/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20111217215935) do
ActiveRecord::Schema.define(:version => 20111224181356) do

create_table "users", :force => true do |t|
t.string "name"
Expand All @@ -25,6 +25,7 @@
t.boolean "receive_email"
t.text "description"
t.datetime "birth_date"
t.float "money"
end

end

0 comments on commit e7f132d

Please sign in to comment.