更新has_many / belong_to关系中大量关联对象的行(Rails 4,PostgreSQL 9.4,activeadmin) [英] Update massive number of rows of associated objects in has_many/belong_to relations (Rails 4, postgresql 9.4, activeadmin)
问题描述
在创建模型交易时,我使用after_create在DealPrize表上创建奖品。
交易和DealPrize有一个属于/ has_many关系:一个交易具有
它的工作原理是这样的:在我的管理面板(使用activeadmin)中,在Deal内,我有一个'prize列-number',然后我使用after_create,以便每次管理员创建新交易时,应用程序都会使用这award_number列,并在DealPrize表内创建此数量的奖品(插入必要的行=>经常超过300,000) 。
因此,我创建了一个交易,该应用自动创建了大量关联对象(奖品),例如300,000个。
问题是我希望两天后将奖金数从300,000更改为272,000(少奖)或324,000(更多奖)。
如何更新创建的交易并告诉我的Rails应用更新关联数量ted奖品(删除一些或添加一些)而又不让其消失并重新创建整个Deal对象?
此外,我还需要一种快速的方法(例如我使用的一种方法)创建Deal =>原始sql和事务,因为一次创建的行数非常高。)
modals Deals.rb
has_many:deal_prizes,从属::delete_all
after_create:create_deal_prizes
CONNECTION = ActiveRecord :: Base.connection.raw_connection
def create_deal_prizes
begin
CONNECTION.describe_prepared('yokoatxz')
急救PG :: InvalidSqlStatementName
CONNECTION.prepare('yokoatxz','INSERT INTO deal_prizes(deal_id,created_at,updated_at,admin_user_id)值($ 1,$ 2,$ 3,$ 4)')
结束
Deal.transaction做
self.prizes_number.times做| i |
CONNECTION.exec_prepared('yokoatxz',[{值:self.id},
{值:'2009-01-23 20:21:13'},
{值:' 2009-01-23 20:21:13'},
{值:self.admin_user_id}
])
结束
结束
结束
感谢您的帮助,Mathieu
好吧,我认为,如果您只是想更改deal_prizes的数量,则可以在Deal上使用before_save回调来测试priest_number和prize_number_was之间的差异,并适当地发出插入或删除语句。 / p>
我希望对删除操作执行以下操作:
deal_prizes.limit(prize_number_was-奖品编号).delete_all
...如果
您可能想在deal_prizes上使用范围:
def self.deletable
其中(:taken => false)
end
...以应用可删除行的条件,然后将其合并到交易关联中...
has_many:deletable_deal_prizes,-> {merge(DealPrize.deletable)} ,: class_name => DealPrize
...因此您可以:
deleteable_deal_prizes.limit(prize_number_was-奖品编号).delete_all
When creating a model Deal, I use an after_create to create prizes on the DealPrize table.
Deal and DealPrize have a belong to/has_many relations: a Deal has many Deal prizes and a Dealprize belongs to a Deal.
It works like this: on my admin panel (using activeadmin), inside a Deal, I have a column 'prize-number' and I use an after_create so that every time the admin creates a new deal, the app takes this prize_number column, and create this volume of prizes (inserting as many rows as necessary=> often more than 300,000) inside the DealPrize table.
So I create a Deal, and automatically, the app creates a huge number of associated objects (prizes) say 300,000.
The problem is I might wish 2 days later to change the prize number from 300,000 to 272,000 for example (less prizes) or 324,000 (more prizes).
How can I update the created Deal and tell my Rails app to update the number of associated Prizes (removing some or adding some) without deleeting and recreating the whole Deal object ?
Also, I need a fast way (like the one I use to create the Deal => raw sql and transaction as the number of rows to create at once is very high).
modals Deals.rb
has_many :deal_prizes, dependent: :delete_all
after_create :create_deal_prizes
CONNECTION = ActiveRecord::Base.connection.raw_connection
def create_deal_prizes
begin
CONNECTION.describe_prepared('yokoatxz')
rescue PG::InvalidSqlStatementName
CONNECTION.prepare('yokoatxz', 'INSERT INTO deal_prizes (deal_id,created_at,updated_at,admin_user_id) values ($1, $2, $3, $4)')
end
Deal.transaction do
self.prizes_number.times do |i|
CONNECTION.exec_prepared('yokoatxz', [ { value: self.id},
{ value: '2009-01-23 20:21:13' },
{ value: '2009-01-23 20:21:13' },
{ value: self.admin_user_id }
] )
end
end
end
Thanks for your help, Mathieu
Well I think that if you just wanted to change the number of deal_prizes then you could use a before_save callback on the Deal to test for a difference between prize_number and prize_number_was, and issue either an insert or delete statement appropriately.
I expect for the delete you'd do something like:
deal_prizes.limit(prize_number_was - prize_number).delete_all
... if you didn't care which were deleted.
You would probably want to use a scope on the deal_prizes:
def self.deletable
where(:taken => false)
end
... to apply the condition by which rows can be deleted though, and then merge this into the association on deal ...
has_many :deletable_deal_prizes, -> {merge(DealPrize.deletable)}, :class_name => "DealPrize"
... so you can:
deleteable_deal_prizes.limit(prize_number_was - prize_number).delete_all
这篇关于更新has_many / belong_to关系中大量关联对象的行(Rails 4,PostgreSQL 9.4,activeadmin)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!