如何在同一模型上为少数关联分配更改?

时间:2015-11-13 16:31:14

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

我有一个类Dealer,在另一个类上几乎没有关联:

class Dealer < AR::Base
  has_many :campaigns
  has_many :published_campaigns, class: 'Campaign', -> { published }
  has_many :unpublished_campaigns, class: 'Campaign', -> { unpublished }
end

class Campaign < AR::Base
  scope :published, -> { where(published: true) }
  scope :unpublished, -> { where(published: false) }
end

因此,存在关联的记录:

dealer = Dealer.first
dealer.campaigns.pluck(:id) # => [1, 2, 3, 4]
dealer.published_campaigns.pluck(:id) # => [1, 2]
dealer.unpublished_campaigns.pluck(:id) # => [3, 4]

我需要一种方法,可用于发布少量广告系列ID并取消发布其余内容。类似的东西:

dealer.publish_ids([2,3]) # another associated campaign_ids will become unpublished
dealer.reload
dealer.published_campaigns.pluck(:id) # => [2, 3]
dealer.unpublished_campaigns.pluck(:id) # => [1, 4]

请帮我写这个方法。

警告:我将在控制器中使用此方法(带质量分配和强参数),因此我需要预见记录不会被保存的情况(所以,它似乎我需要在我的协会中使用:autosave这样的东西

2 个答案:

答案 0 :(得分:0)

我有一个表单可以将id传递给控制器​​,然后是一个像这样的控制器方法

def publish_multiple
  @dealer = Dealer.find(params[:id]) # unless you have some sort of current dealer method
  @dealer.campaigns.where(id: params[:campaign_ids]).update_all(published: true)
  @dealer.campaigns.where.not(id: params[:campaign_ids]).update_all(published: false)
end

使用update all不会进行验证或回调。

答案 1 :(得分:0)

-

您最好在has_many :campaigns上使用ActiveRecord Association Extensions {/ 3>}。

#app/models/dealer.rb.
class Dealer < ActiveRecord::Base
   has_many :campaigns do
      def publish ids
          where(id: ids).update(published: true)
          where.not(id: ids).update(published: false)
      end

      def unpublished
          where(published: false)
      end
      def published
          where(published: true)
      end
   end
end

这样您就可以拨打@dealer.campaigns.published&amp;分别为@dealer.campaigns.unpublished

使用上面的代码,您将能够使用以下内容:

@dealer = Dealer.find params[:id]
@dealer.campaigns.publish [1,2,3]

这仅适用于与campaigns相关联的dealer

-

如果您想要一般广告系列,那么您最好在Campaign模型中使用类方法:

#app/models/campaign.rb
class Campaign < ActiveRecord::Base
   def self.publish ids
       where(id: ids).update(published: true)
       where.not(id: ids).update(published: false)
   end
end

这将允许您使用:Campaign.publish [1,2,3]