多个相同类型的嵌套属性

时间:2013-06-30 17:54:13

标签: ruby ruby-on-rails-3.2 nested-attributes

我有两个模型 - “符号”和“用户”。在其他属性中,符号具有“created_by_id”和“updated_by_id”属性,这些属性是创建/更新某个符号条目的用户的id。

假设我想显示带有“symbol”属性的符号表,以及每个符号条目的嵌套“created by”和“updated by”(user.username)属性。结果表应如下所示:

symbol     created_by    updated_by
------------------------------------
symbol1    username1     username2
symbol2    username1     username2

我怎样才能做到这一点?我想我的Symbol模型中需要accepts_nested_attributes_for :user并且可能需要has_one :user(?)。我的用户模型中是否还需要belongs_to :user

模型设置正确后,如何在我的视图中访问与“created_by_id”和“updated_by_id”关联的用户的用户名?

我有一个编辑表单,我使用这样的嵌套表单(工作正常):

<%= form_for @symbol do |f| %>
  Symbol: 
  <%= f.text_field :symbol %>
  <%= f.fields_for :kanji do |kf| %>
    Meaning:
    <%= kf.text_field :meaning %>

    Onyomi:
    <%= kf.text_field :onyomi %>

    Kunyomi:
    <%= kf.text_field :kunyomi %>
  <% end %>
  <%= f.submit "Save" %>
<% end %>

但在这种情况下我无法弄清楚如何做类似的事情,我有两个与同一符号相关联的嵌套属性。

我是rails的新手,所以也许我完全知道如何做错了。如果有一个比我刚才解释的要好的话,请纠正我。

编辑:这是模特。第一个实际上叫做JSymbol,但问题仍然存在。

class JSymbol < ActiveRecord::Base
  belongs_to :j_symbol_type
  has_one :kanji, :dependent => :destroy
  has_one :radical, :dependent => :destroy
  has_one :vocabulary, :dependent => :destroy

  attr_accessible :created_by_id, :updated_by_id, :symbol, :j_symbol_type_id, :level
  attr_accessible :kanji_attributes, :radical_attributes, :vocabulary_attributes

  accepts_nested_attributes_for :kanji, :radical, :vocabulary
end

用户模型。

class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable, :timeoutable

  attr_accessible :username, :email, :password, :password_confirmation, :remember_me

  validates :username, :presence => true, :uniqueness => true
end

这当然没有user-jsymbol关系,因为我不确定在那里添加什么样的关系..它应该类似于JSymbol模型中的has_one :user和用户模型中的belongs_to :j_symbol除了它需要以某种方式完成两次..还有在每个符号的action方法中调用.build方法的问题。

2 个答案:

答案 0 :(得分:1)

这样的事情应该有效:

class Symbol < ActiveRecord::Base
  has_many :creators, class_name: "User",
                          foreign_key: "created_by_id"
  has_many :updaters, class_name: "User",
                          foreign_key: "updated_by_id" 

  belongs_to :creator, class_name: "User"
end

然后使用:

   symbol | symbol.creator.name |  symbol.updater.name

仍然,我在我的应用程序上尝试这个,所以我不确定它是100%。

修改

class Symbol < ActiveRecord::Base
  has_one :creator, :class_name => User, :foreign_key => 'created_by_id'
  has_one :updater, :class_name => User, :foreign_key => 'updated_by_id'
end

答案 1 :(得分:0)

rmagnum2002让我意识到我可以在这里使用foreign_key参数后,我开始谷歌搜索&#34;将多个外键锁定到同一个表&#34;,偶然发现一堆过时的SO答案没有&#39 ; t work并最终找到了this article,它帮助我编写了有效的代码。

所以,这是我在JSymbol模型中的关系:

belongs_to :created_by, :class_name => User, :foreign_key => "created_by_id"
belongs_to :updated_by, :class_name => User, :foreign_key => "updated_by_id"

这个来自用户模型:

has_many :occurances_as_created_by, :class_name => JSymbol, :foreign_key => "created_by_id"
has_many :occurances_as_updated_by, :class_name => JSymbol, :foreign_key => "updated_by_id"

我没有在动作方法中添加任何内容,这就是我在视图中添加的内容:

<%= j_symbol.created_by.username %>
<%= j_symbol.updated_by.username %>

这是SQL中发生的事情,如果有人感兴趣的话(这意味着它实际上是通过单独的选择查询而不是连接来完成的,所以我可能会继续寻找更好的解决方案):

JSymbol Load (0.3ms)  SELECT "j_symbols".* FROM "j_symbols" 
JSymbolType Load (0.3ms)  SELECT "j_symbol_types".* FROM "j_symbol_types" 
User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 7 LIMIT 1
User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 8 LIMIT 1
CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 8 LIMIT 1
CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 8 LIMIT 1
Rendered j_symbols/index.html.erb within layouts/j_symbols (7.8ms)
CACHE (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 8 LIMIT 1