ruby-on-rails - 创建具有两个belongs_to关联的模型的最佳实践?

标签 ruby-on-rails ruby ruby-on-rails-3

这是我经常遇到的一致性问题。

让我们考虑一个典型的论坛:

  • 用户可以创建帖子
  • 帖子属于某个主题
  • 帖子也属于创建帖子的用户

在这两个选项之间进行选择的最佳实践是什么:

# Initialize @post on the User
def create
  @post = current_user.posts.build(params[:post])
  @post.topic_id = @topic.id
  if @post.save
    ...
  end
end

或者

# Initialize @post on the Topic
def create
  @post = @topic.posts.build(params[:post])
  @post.user_id = current_user.id
  if @post.save
    ...
  end
end

或者有没有更好的方法,考虑到在上面的例子中,要么@post's user_idtopic_id必须添加到 attr_accesssible (感觉很怪异)?

最佳答案

我设法找到的最简洁的方法是使用 CanCan:当有规则 can :create, Post, :user_id => user.id 并在您的代码中添加 load_resource Controller 它将设置属性。

但它并不总是合适。如果有一些通用的解决方案来一次性初始化嵌套对象,那就太好了。

更新。我想出了另一个选择:

@post = @topic.posts.where(user_id: current_user.id).build(params[:post])

一般来说,所有这些方法都打破了 Law of Demeter 。最好封装在模型的方法中,如下所示:

class Topic < ActiveRecord::Base
  def new_post(params={}, author=nil)
    posts.build(params).tap {|p| p.user = author}
  end
end

然后在 Controller 中:

@post = @topic.new_post(params[:post], current_user)

关于ruby-on-rails - 创建具有两个belongs_to关联的模型的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6834028/

相关文章:

ruby-on-rails - 使用 devise gem 时,浏览器关闭时用户自动注销

ruby-on-rails - Rails sanitize 删除默认允许的标签

ruby - 如何使用 rvmsudo 运行 Chef 命令(使用 rvm 安装乘客)

ruby-on-rails - 如何在rails上实现文本提取?

ruby-on-rails - 在 Rails 3.1 中可以使用 << 运算符插入多个对象吗?

ruby-on-rails - 将 Ruby on Rails 安装到 Synology DSM 5.2 时出现问题

ruby-on-rails - 将变量传递给 Rails 部分

ruby-on-rails - Minitest - 具有方法级粒度的测试套件

ruby-on-rails - 查询 Activerecord HABTM 关系以包含数组的所有元素

ruby-on-rails-3 - 为特定模型自定义 rails_admin 删除操作