Rails 3.0.7 + Decent Exposure Gem
我正在为具有一个关联属性的模型创建表单:
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
允许用户从选择框中选择一个相关项目。所以我的基本控制器看起来像这样:
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
这很好用,但需要调整功能以克隆上一个项目而不是创建一个新项目。所以我补充说:
default_exposure do |name|
collection = name.to_s.pluralize
if respond_to?(collection) && collection != name.to_s && 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
这完全有效,但它几乎毁了我的乐趣。它超级巨大,令人难以置信的草率。必须有更好的方法吗?
答案 0 :(得分:0)
为什么不在模型的回调之前而不是在控制器中执行此操作?
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