Chr*_*her 31 activerecord ruby-on-rails
如果它的属性在父模型的表单中被消隐,我想销毁嵌套模型 - 但是,ActiveRecord::Callbacks如果模型为空,则看起来不会调用它.
class Artist < ActiveRecord::Base
using_access_control
attr_accessible :bio, :name, :tour_dates_attributes
has_many :tour_dates, :dependent => :destroy
accepts_nested_attributes_for :tour_dates, :reject_if => lambda { |a| a[:when].blank? || a[:where].blank? }, :allow_destroy => true
validates :bio, :name :presence => true
def to_param
name
end
end
Run Code Online (Sandbox Code Playgroud)
和
class TourDate < ActiveRecord::Base
validates :address, :when, :where, :artist_id, :presence => true
attr_accessible :address, :artist_id, :when, :where
belongs_to :artist
before_save :destroy_if_blank
private
def destroy_if_blank
logger.info "destroy_if_blank called"
end
end
Run Code Online (Sandbox Code Playgroud)
我有一个艺术家的表格,用于fields_for显示艺术家相关旅行日期的字段,用于编辑和添加新的旅行日期,但如果我只是删除一个旅游日期(删除它),destroy_if_blank则永远不会被调用.据推测,Artist控制器的@artist.update_attributes(params[:artist])行不会考虑值得更新的空白实体.
我错过了什么吗?有没有解决的办法?
小智 71
我会保留:reject_if块,但如果满足条件,则在属性哈希中插入:_destroy => 1.(这在将_destroy添加到表单代码不方便的情况下很有用.)
你必须做一个额外的检查,以查看记录是否存在,以便返回正确的值,但以下似乎适用于我的所有情况.
accepts_nested_attributes_for :tour_dates, :reject_if => :reject_tour, :allow_destroy => true
def reject_tour(attributes)
exists = attributes['id'].present?
empty = attributes.slice(:when, :where).values.all?(&:blank?)
attributes.merge!({:_destroy => 1}) if exists and empty # destroy empty tour
return (!exists and empty) # reject empty attributes
end
Run Code Online (Sandbox Code Playgroud)
您可以应用在所有的属性都是空白的只是改变了empty计算:
empty = attributes.except(:id).values.all?(&:blank?)
Run Code Online (Sandbox Code Playgroud)
小智 6
你有代码说如果'where'或'when'是空白的话应该忽略记录,在accepts_nested _attributes行上删除reject_if,你的destroy_if空白可能会被调用.
通常要销毁,你可以_destroy在嵌套记录上设置一个 属性,查看文档http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
此外,今天只使用了一些茧,并认为它很棒,https://github.com/nathanvda/cocoon
我今天设法做了这样的事情.就像@shuriu说的那样,你最好的选择是删除reject_if选项并自己处理破坏.mark_for_destruction派上用场:
class Artist < ActiveRecord::Base
accepts_nested_attributes_for :tour_dates
before_validation :mark_tour_dates_for_destruction
def mark_tour_dates_for_destruction
tour_dates.each do |tour_date|
if tour_date.when.blank? or tour_date.where.blank?
tour_date.mark_for_destruction
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
与史蒂夫肯沃西的回答类似,没有局部变量。
accepts_nested_attributes_for :tour_dates, :reject_if => :reject_tour, :allow_destroy => true
def reject_tour(attributes)
if attributes[:when].blank? || attributes[:where].blank?
if attributes[:id].present?
attributes.merge!({:_destroy => 1}) && false
else
true
end
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17252 次 |
| 最近记录: |