开发者

Overriding Decent Exposure Properly

Rails 3.0.7 + Decent Exposure Gem

I'm creating a form for a model with one associated attribute:

class Foo
  has_many :bars

  def self.build_next(attributes={})
    if item = last.try(:clone)
      # ... overrides
    else
      item = self.new
    end

    item.attributes = attributes
    return entry
  end
end

The user is allowed to select from a select box one of the associated items. So my basic controller looks like this:

class FooController < ApplicationController
  expose(:foos)
  expose(:foo)
  expose(:bar)

  def new
   #...
  end

  def create
    if foo.save
      redirect_to foo
    else
      render :action => 'new'
    end
  end
end

This works great, but the functionality needs to be adjusted to clone the previous item instead of creating a new one. So I've added:

  default_exposure do |name|
    collection = name.to_s.pluralize
    if respond_to?(collection) && collection != name.to_s &&am开发者_如何学运维p; send(collection).respond_to?(:scoped)
      proxy = send(collection)
    else
      proxy = name.to_s.classify.constantize
    end

    if id = params["#{name}_id"] || params[:id]
      proxy.find(id).tap do |r|
        r.attributes = params[name] unless request.get?
      end
    else

      # NEW CODE
      if name == :foo && params[:action] == :new.to_s
        # override
        Foo.build_next
      else
        proxy.new(params[name])
      end

    end
  end

This totally works, however it pretty much ruins my fun. It's super huge and is incredibly sloppy. There must be a better way right?


Why not do this in a before callback on the model instead of in the controller?

e.g.

class Foo < ActiveRecord::Base
  has_many :bars
  before_validation_on_create :build_next
  def build_next
    if prev_item = Foo.last.try(:clone)
      # ... overrides
    else
      prev_item = Foo.new
    end

    attributes.reverse_merge! prev_item.attributes 
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜