0

我正在创建一个论坛软件。我想实现关闭主题功能。关闭主题将阻止任何人为已关闭的主题创建帖子。

我目前的实现

  • TOPIC有很多帖子
  • 创建 TOPIC 时,默认情况下,还会为该 TOPIC 创建一个 POST。基本上 TOPIC 有一个title并从 POST 中派生出内容主体content
class AddClosedToTopic < ActiveRecord::Migration
  def change
    add_column :topics, :closed, :boolean, default: false
  end
end
  • TOPIC 有一个名为 的列closed。如果closed为真,则主题关闭。默认情况下,它设置为 false。
  • 每当用户尝试创建帖子时,我都会使用下面的验证来检查主题是否已关闭。
class Post < ActiveRecord::Base
  . . .
  validate :cannot_create_replies_to_closed_topic

  # custom validation methods
  def cannot_create_replies_to_closed_topic
    topic = Topic.find_by_id(topic_id)
    if topic.closed?
      errors.add(:content, "can't be created for a topic that is closed")
    end
  end
end

问题

这种方式对于在创建后一段时间内关闭的 TOPIC 非常有效。但是,当我创建一个新 TOPIC 时,它就会出现问题。

因为在 POST 验证中,我这样做topic = Topic.find_by_id(topic_id)了,当前正在创建的新主题不会在数据库中。所以它抛出 NoMethodError。

NoMethodError in TopicsController#create
undefined method `closed?' for nil:NilClass

app/models/post.rb:16:in `cannot_create_replies_to_closed_topic'
app/controllers/topics_controller.rb:21:in `create'

可能的解决方案?

我想我有一些方法可以引用在 POST 验证中以某种方式创建的当前主题,我认为这个问题可以解决。

我怎样才能做到这一点?或者你们有其他方法可以解决这个问题吗?

4

1 回答 1

0

您可以after_create在主题模型中尝试类似回调的方法,以便仅在创建主题后创建帖子,并在该方法中设置 topic_id。

像这样的东西:

 after_create :create_initial_post

 def create_initial_post
   post = Post.new(:topic_id => self.id)
   post.save
 end

这应该可以解决您的问题。您可能必须修改一些代码以确保它首先创建主题,然后它应该在此之后创建初始帖子。您可能还想修改您的cannot_create_replies_to_closed_topic方法以确保可以创建初始帖子。

希望这会为您指明正确的方向!

于 2012-07-01T20:29:59.113 回答