【问题标题】:Ruby on Rails: Creating a link based on new database entryRuby on Rails:基于新数据库条目创建链接
【发布时间】:2017-01-15 14:23:34
【问题描述】:

我正在更新我大约 2 年前创建的网站。这是我第一个真正的网站,但我犯了一些错误(有些错误比其他人更严重)。

显然我最大的一项工作是从视图中调用数据库。

非常确定有更好的方法来做到这一点:

用例:

  1. 有人填写了一个新主题的表格,填充了主题表,他们被标记为“已注​​册”,Subject.enrolled = 1
  2. 基于此,我现在需要在其他 5 个表(如 Baseline)中创建一条记录
  3. 从这里下坡,这是我的方法

    • 根据Subject(sub)中的subject_id判断记录是否存在

      <$ if Baseline.where(subject_id: sub.subject_id).first != nil $>
      
    • 如果不存在,则创建记录,(否则显示链接)

      <%= Baseline.create(subject_id: sub.subject_id) %>
      
  4. 这一切都发生在视图中,并创建一个前端表,其中包含指向流程中每条记录的链接。所以我正在基于 for-loop 逻辑创建记录...

问题: 所以我在寻找方向。我不想猜测如何做到这一点——我很确定模型/控制器应该这样做——我想学习如何正确地做到这一点。如何根据表中的值自动创建记录?

感谢您的宝贵时间。

【问题讨论】:

标签: ruby-on-rails ruby database model-view-controller


【解决方案1】:

不太确定您的域和代码是什么样子,但要回答这个问题:“如何根据表中的值自动创建记录?”,您似乎可以使用 ActiveRecord 回调,如下所示:

class Subject < ActiveRecord::Base
  after_commit :create_baseline_if_enrolled, on: [:create, :update]

  private

  def create_baseline_if_enrolled
    return unless enrolled?

    # enrolled? == true, you may create these models here
  end
end

回答您的问题: 这取决于:) 这只是一种可能的解决方案。另一种方法是将这样的自定义逻辑放在您的 SubjectsController 中,并直接从#create、#update 方法中调用它。两种方法都有优点和缺点。例如,滥用回调(在任何地方)会降低代码的可读性和调试难度。另一方面,将这样的逻辑放在控制器中会给您带来负担,如果您碰巧在其他地方编辑主题(但更明确),您必须记住调用它。无论您选择哪种方式,请记住不要让您的类太胖,例如,一旦您觉得它失控了,就尝试使用服务对象模式来分离此类自定义逻辑。 :) 不要忘记测试——当出现问题时,测试让重构变得更容易。

【讨论】:

  • 这看起来像我应该做的...... after_save 什么时候被调用?主题可以在一段时间内作为空白值注册,然后在将来的任何时间将其更改为 1。我找到了一个 after_update 函数,也许我应该使用它?
  • 实际上,我认为在 after_commit 回调中会更适合您的用例:apidock.com/rails/ActiveRecord/Transactions/ClassMethods/… 我已经更新了代码,说明如何确保它在创建和更新时都被执行。跨度>
  • 我明白了。我将您的答案标记为正确答案,我认为这让我走上了正确的道路。还有一个问题,这应该放在模型还是控制器中?我认为该模型适用于诸如此类的数据库,但是 :create 和 :update 是控制器功能。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 2014-03-07
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
  • 2023-04-03
  • 1970-01-01
相关资源
最近更新 更多