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
Теперь, в случае сценариев миграции, вы просто создадите столбцы, которые вы назвали.
ОБНОВИТЬ:
Хорошо, если мы просто реорганизовать ваши требования
- Пользователь может иметь много правил.
- Многие правила могут быть применены к одному пользователю
- Один пользователь может иметь владельца, который также является пользователем
- У одного владельца будет много подчиненных, которые тоже являются Пользователями.
Затем я обновил мои коды выше. Пожалуйста, посмотрите, поможет ли это сейчас.