在尝试访问时不引人注目地为关联创建记录?

发布于 2024-07-21 07:23:02 字数 372 浏览 9 评论 0原文

我在两个模型之间有一个简单的 has_one/belongs_to 关系。

这是我的应用程序中的一个新关联,因此有许多记录尚未创建关联记录。

在我的整个应用程序中,我假设模型具有关联,并且我正在访问它的属性和方法。 但是,由于关联不存在,我遇到了很多错误。

我想做的是,每当第一次通过其任何方法和属性访问关联记录时,不引人注意地动态构建关联记录。 记录中有数据并不重要,我只需要它存在,以便我调用的那些方法可以构建数据。

编辑:我不想在我尝试访问关系的所有实例上检查和创建记录,因此理想情况下,这需要在模型本身而不是在我的控制器中完成任何地方。

有什么想法吗?

谢谢!

I have a simple has_one/belongs_to relationship between two models.

This is a new association in my application so there are many records that do not yet have the associated record created.

Throughout my application I'm assuming the model has the association and I'm accessing its attributes and methods. However, because the association doesn't exist, I'm running into a lot of errors.

What I would like to do is unobtrusively build the associated record on the fly whenever it's access for the first time through any of its methods and attributes. It does not matter that there is data in record, I simply need it to exist so those methods I'm calling can build the data.

Edit: I do not want to check and create the record on all of the instances where I'm trying to access the relationship, so idealy this needs to be done on the model itself and not in my controllers anywhere.

Any thoughts?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

粉红×色少女 2024-07-28 07:23:02

这就是我们最终得到的效果。 我没有写它(一个同事写的),但它通过了我之前为本案例编写的失败测试。

def stats_with_create
  stats_without_create || create_stats
end
alias_method_chain :stats, :create

Here's what we ended up with that did the trick. I didn't write it (a co-worker did) but it passes the previously failing tests that I wrote for this case.

def stats_with_create
  stats_without_create || create_stats
end
alias_method_chain :stats, :create
绳情 2024-07-28 07:23:02

在控制器中,您可以在 show 方法中放置类似的内容(未经测试,但它应该给您一个想法:

@thing = Thing.find params[:id]
if @thing.other_thing.nil?
  @thing.other_thing = OtherThing.new.save!
  @thing.save!
end

这并不理想,您可能可以通过放置一个来清理它)事物模型中的方法将检查并创建相关模型,而不是将其放入控制器中。

另一种选择是创建一个用于访问 other_thing 的新访问器,根​​据需要创建它。 然而,

正确的做法可能是修复您的数据,无论是在迁移中还是直接正确地创建相关模型。

In the controller, you could put something like this in the show method (untested, but it should give you an idea:

@thing = Thing.find params[:id]
if @thing.other_thing.nil?
  @thing.other_thing = OtherThing.new.save!
  @thing.save!
end

This isn't ideal, and you could probably clean it up a lot by putting a method in the Thing model that would check for and create the related model instead of putting it into your controller.

Another option would be to create a new accessor that you use to access the other_thing, creating it as required.

However, the correct thing to do is probably to fix your data, either in a migration or directly, creating the related models properly.

萧瑟寒风 2024-07-28 07:23:02

直接的答案是重写关系的方法。 调用时它将检查记录是否存在,如果不存在则创建它。

但是,我建议您使用迁移来预先创建所有记录。

The direct answer is to override method for the relationship. When called it will check if the record exists and create it if it doesn't.

However, I would recommend that you use a migration to create all of the records up front.

活泼老夫 2024-07-28 07:23:02

我以前做过这类事情,但不是在模型级别。 我已经在控制器级别上使用 before_filter 完成了此操作,该过滤器在需要访问尚存在或尚不存在的模型关联的所有方法之前运行。

我刚刚意识到可以在模型中使用 after_find 和 after_initialize 回调。

你可以坚持:

def after_initialize
   association.build if association.nil?
end

在你的模型中,它应该可以解决你的问题..(免责声明:未经我测试):)

I have done this type of thing before but not on the model level. Ive done it on the controller level with a before_filter that ran before all methods which needed to access the model association that did or did not exist yet.

I just realized there is the after_find and after_initialize callbacks that you can use in the model.

You could stick:

def after_initialize
   association.build if association.nil?
end

in your model and it should solve your problems.. (disclaimer: untested by me) :)

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