ActiveRecord 并从关系、find_by_sql 或named_scope 中获取未使用的记录?
一些上下文:
我有一些看起来像这样的模型
Actor has_many Acts
Act owns_to Actor、belongs_to Decision
Decision has_many Acts、belongs_to Prompt
Prompt has_many Decisions
我需要做的是在 ActorsController 中,获取一个尚未使用的随机 Prompt所有可用的提示。
在我的 Rails 应用程序中,Actor 会收到提示,让他们做出一些选择。当他们做出选择(决策)时,该选择将作为 Act 保存在数据库中。
我已经尝试过named_scope和find_by_sql的各种迭代,但没有一个起作用,我什至不确定我的想法是否正确,因为有很多模型在工作,而且我似乎不知道从哪里开始。
我希望这能让我了解我所面临的问题。我什至希望能得到一个制定攻击计划的一般性指示。
谢谢!
编辑
经过几个小时的思考,我已经得到了一些东西,但它非常混乱,而且我的日志充满了 SQL 调用,所以它绝对可以经得起挑剔的眼光。
在 Prompt 模型中:
named_scope :available, lambda { |used|
{ :conditions => ["id NOT IN (?)", used ] }
}
在 Actor 模型中:
def used_prompts
prompts = Array.new
if self.acts && self.acts.length >= 1
self.acts self.acts.each { |act| prompts.insert(0, act.decision.prompt.id) }
return prompts.sort
else
return [0]
end
end
在 ActorsController 中:
@prompt = Prompt.available(@actor.used_prompts).find(:first, :order => "RAND()")
显然,used_prompts 中的 if 块是这里的一个罪魁祸首,但我不知道更好的方法来处理这个问题,因为我无法执行 self.acts。决定。每一个或一些这样的事情。也许有人可以教我:)
Some context:
I have some models that look like this
Actor has_many Acts
Act belongs_to Actor, belongs_to Decision
Decision has_many Acts, belongs_to Prompt
Prompt has_many Decisions
What I need to do is in the ActorsController, get a random Prompt that has not been used yet of all the available Prompts.
In my rails app, Actors are presented with prompts that give them a few choices to make. When they make a choice (Decision), that is saved in the db as an Act.
I've tried various iterations of named_scope and find_by_sql, but none worked, and I'm not even sure if my thinking was right to begin with on them, since there are so many models at work, and I don't seem to know where to start.
I hope this gives an idea of what I'm up against. I'd appreciate even a general pointer to form a plan of attack even.
Thanks!
edit
After chewing on this for a couple hours, I've got something working but it's very messy, and my logs are filled with SQL calls, so it could definitely stand a critical eye.
In the Prompt model:
named_scope :available, lambda { |used|
{ :conditions => ["id NOT IN (?)", used ] }
}
In the Actor model:
def used_prompts
prompts = Array.new
if self.acts && self.acts.length >= 1
self.acts self.acts.each { |act| prompts.insert(0, act.decision.prompt.id) }
return prompts.sort
else
return [0]
end
end
And in the ActorsController:
@prompt = Prompt.available(@actor.used_prompts).find(:first, :order => "RAND()")
Obviously the if block in used_prompts is one guilty party here, but I don't know a better way to deal with that since I can't do self.acts.decisions.each or some such thing. Maybe someone can school me :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
最简单的做法是在决策模型上添加 after_create 或类似的回调,将关联的提示标记为已使用。您也可以使用一些联接来实现此目的,但这需要更多的工作,并且可能会导致可扩展性问题(如果您关心的话)。
The simplest thing to do would be to add a after_create or similar callback on the Decision model that marks the associated prompt as used. You could also achieve this using some joins, but that would take a little more work, and will possibly lead to scalability issues (if you care).