Rails ActiveRecord реализует отношения

Помогите мне с миграцией базы данных и моделью в Rails, я попытался найти самореференции, а что нет, но я не могу делать головы или хвосты... Я застрял, так сказать...

В основном я хочу две модели, модель пользователя и модель правила.

В модели User я хочу указать владельца пользователя, который является другим пользователем, может быть только один владелец, пользователь может быть владельцем самого себя.

И модель правила, в которой я также хочу указать владельца правила (пользователь) (пользователь может быть владельцем многих правил) и пользователя, к которому применяется это правило (пользователь) (пользователь может иметь много правил).

Итак, мне нужны две миграции и две модели, я начну и, надеюсь, вы сможете разобраться в том, что я пытаюсь сделать..

class User < ActiveRecord::Base
  belongs_to :user #?
  has_one :user    # as in owner
  has_many :rules  # rules for given user and rules that are created by this user
  ... #and some more similar entries
end

а также

class Rule < ActiveRecord::Base
  belongs_to :user # as in owner of rule and rule for user
end

и я совершенно не уверен, что писать в миграциях..

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.string :username

      #owner?

      #stuff left out
      t.timestamps
    end
  end
end

а также

class CreateRules < ActiveRecord::Migration
  def change
    create_table :rules do |t|
      t.string :title

      #rule for?
      #owner?

      #stuff left out
      t.timestamps
    end
  end
end

Как мне это реализовать?

3 ответа

Вам нужны три таблицы, потому что "правило, примененное к пользователю" - это "многие ко многим", поэтому для него нужна таблица соединений.

Вам также необходимо переименовать либо "правило, созданное пользователем", либо "правило, примененное к пользователю", так как в противном случае у вас будут конфликты имен.

Таблицы:

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      #stuff left out

      t.references :owner

      #stuff left out
    end
  end
end

class CreateRules < ActiveRecord::Migration
  def change
    create_table :rules do |t|
      #stuff left out

      t.references :owner

      #stuff left out
    end
  end
end

class CreateRulesUsers < ActiveRecord::Migration
  def change
    create_table :rules_users do |t|
      t.references :user
      t.references :rule
    end
  end
end

модели

  • пользователь

    has_many :owned_users, :class_name => "User", :foreign_key => "owner_id", :inverse_of => :owner
    belongs_to :owner, :class_name => "User", :foreign_key => "owner_id", :inverse_of => :owned_users
    has_and_belongs_to_many :rules # uses the join table
    has_many :owned_rules, :class_name => "Rule", :foreign_key => "owner_id", :inverse_of => :owner
    
  • правило

    belongs_to :owner, :class_name => "User", :foreign_key => "owner_id", :inverse_of => :owned_rules
    has_and_belongs_to_many :users # uses the join table, it's the users to which the rule applies
    

Что вам нужно, так это самореференциальная ассоциация

Прочитайте http://edgeguides.rubyonrails.org/association_basics.html и пройдите этот эпизод на RailsCasts. Это демонстрирует именно то, что вы ищете.

Надеюсь, поможет

Удачи.:)

#Models/user.rb
class User < ActiveRecord::Base
  belongs_to :owner, :class_name => 'User', :foreign_key => 'owner_id'
  has_many :subordinates, :class_name => 'User'
  has_many :rules, :through => "owner_rules"
end

#Models/OwnerRule.rb
class OwnerRule < ActiveRecord::Base
    belongs_to :users
    belongs_to :rules
end

#Models/Rule.rb
class Rule < ActiveRecord::Base
    has_many :users, :through => "owner_rules"
end

Это руководство rubyonrails имеет хорошее руководство по этому вопросу.

Итак, дело в том, user у объекта будет два метода owner а также subordinates, Если вы позвоните user.owner тогда он вернет пользователя с идентификатором равным user.owner_id.
Если вы позвоните user.subordinates тогда он вернет всех пользователей, имеющих user.id в столбце owner_id.

Дайте мне знать, если сделать это немного запутанным или нет:P

Теперь, в случае сценариев миграции, вы просто создадите столбцы, которые вы назвали.

ОБНОВИТЬ:

Хорошо, если мы просто реорганизовать ваши требования

  • Пользователь может иметь много правил.
  • Многие правила могут быть применены к одному пользователю
  • Один пользователь может иметь владельца, который также является пользователем
  • У одного владельца будет много подчиненных, которые тоже являются Пользователями.

Затем я обновил мои коды выше. Пожалуйста, посмотрите, поможет ли это сейчас.

Другие вопросы по тегам