帮助HABTM:通过

时间:2010-12-28 11:37:58

标签: ruby-on-rails

到目前为止,我目前的HABTM实施工作:has_and_belongs_to_many。通知和隐私都继承自Preference。偏好是STI。我想尝试使用:has_many,:通过关联代替。

模型文件

class User < ActiveRecord::Base
  has_and_belongs_to_many :preferences
end

class Preference < ActiveRecord::Base
  has_and_belongs_to_many :users
end

class Notification < Preference
end

class Privacy < Preference
end

迁移文件

class UsersHaveAndBelongToManyPreferences < ActiveRecord::Migration
  def self.up
    create_table :preferences_users, :id => false do |t|
      t.references :preference, :user

      t.timestamps
    end
  end

  def self.down
    drop_table :preferences_users
  end
end

class CreatePreferences < ActiveRecord::Migration
  def self.up
    create_table :preferences do |t|
      t.string :title
      t.text :description
      t.string :type

      t.timestamps
    end
  end

  def self.down
    drop_table :preferences
  end
end

class DeviseCreateUsers < ActiveRecord::Migration
  def self.up
    create_table(:users) do |t|
      t.string :name
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end

我尝试了以下

class User < ActiveRecord::Base
  has_many :preferences, :through => :preferences_users
end

class Preference < ActiveRecord::Base
  has_many :users, :through => :preferences_users
end

我的表单似乎

  <% Preference.where(:type => 'Notification').all.each do |notification| %>
    <li>
      <%= check_box_tag 'user[preference_ids][]', notification.id, @user.preference_ids.blank? ? false : @user.preferences.include?(notification) %>
      <%= label_tag notification.description %>
    </li>
  <% end %>

Could not find the association :preferences_users in model User

我做错了什么?问题出在我的表格或我的协会中吗?

2 个答案:

答案 0 :(得分:6)

好的让它发挥作用。我需要一个模型PreferencesUser,并且在用户和偏好模型上缺少has_many:preferences_users:

class PreferencesUser < ActiveRecord::Base
    belongs_to :user
    belongs_to :preference
end

class User < ActiveRecord::Base
  has_many :preferences_users
  has_many :preferences, :through => :preferences_users
end

class Preference < ActiveRecord::Base
  has_many :preferences_users
  has_many :users, :through => :preferences_users
end

没有必要改变我的形式。希望这有助于某人

答案 1 :(得分:1)

HABTM关联是为了创建一个N到N的关系,你做得很好,但没那么有用。 has_many关联用于创建1-N关系,是一个不错的选择。

你必须:

  • 在您的用户模型中添加has_many:preferences(就像您一样)
  • 在您的偏好模型中添加belongs_to:user
  • 将user_id添加到您的偏好表

通常我们使用:through来链接没有直接链接的对象,例如连接到文章的用户,因为他们在某些文章上发表了评论。

另一个有用的用法是条件N-N关系,例如'friendship'类:

class Friendship < ActiveRecord::Base
  belongs_to :user
  belongs_to :friend, :class_name => "User"
end

class User < ActiveRecord::Base
  has_many :friends, :through => :friendships, :conditions => "status = 'accepted'"
  has_many :requested_friends, :through => :friendships, :source => :friend, :conditions => "status = 'requested'", :order => :created_at
  has_many :pending_friends, :through => :friendships, :source => :friend, :conditions => "status = 'pending'", :order => :created_at
end 

为了满足您的需求,您可以执行以下操作:

#in you User model
has_many :notifications, :source => :preferences
has_many :privacies, :source => :preferences

#in your Preference model
belongs_to :user