ActiveRecord 并从关系、find_by_sql 或named_scope 中获取未使用的记录?

发布于 2024-10-14 15:45:40 字数 1263 浏览 5 评论 0原文

一些上下文:

我有一些看起来像这样的模型

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

韬韬不绝 2024-10-21 15:45:40

最简单的做法是在决策模型上添加 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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文