使用has_many通过将新对象与现有对象相关联

时间:2013-04-18 01:40:36

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1 ruby-on-rails-3.2

我有两个类用户和项目。用户可以拥有许多项目,并且许多用户可以拥有项目。但是,项目必须至少有一个用户,而用户不必拥有项目。

这就是我目前所拥有的:

class Project < ActiveRecord::Base
    attr_accessible :prj_id, :name
    has_many :ownerships, foreign_key: "project_id", dependent: :destroy
    has_many :users, through: :ownerships
end

class User < ActiveRecord::Base
    attr_accessible :first_name, :last_name, :email, :password, :password_confirmation

    has_many :ownerships, foreign_key: "user_id", dependent: :destroy
    has_many :projects, through: :ownerships
    validates :first_name, presence: true, length: { maximum: 25 }
    validates :last_name, presence: true, length: { maximum: 25 }
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
        uniqueness: { case_sensitive: false }
    validates :password, presence: true, length: { minimum: 6 }
    validates :password_confirmation, presence: true
end

class Ownership < ActiveRecord::Base
    attr_accessible :project_id

    belongs_to :user, class_name: "User"
    belongs_to :project, class_name: "Project"

    validates :user_id, presence: true
    validates :project_id, presence: true
end

因此,在我们创建项目之前,用户必须首先存在。我目前遇到的问题是当我尝试创建一个新项目并将用户附加到新项目时,它不允许我保存,因为用户已经存在于User表中。更具体地说,在rails控制台中:

>> prj = Project.new(prj_id: 'hello', name: 'hello')
>> usr = User.find_by_id(1)
>> prj.users<<usr
>> prj.save

prj.save行未能发出此消息:

(0.1ms)  SAVEPOINT active_record_1
User Exists (0.1ms)  SELECT 1 AS one FROM "users" WHERE (LOWER("users"."email") = LOWER('example@example.com') AND "users"."id" != 1) LIMIT 1
(0.1ms)  ROLLBACK TO SAVEPOINT active_record_1
=> false

是否有办法将新项目与现有用户相关联,在Project表和Ownership表中创建新条目,同时检查用户表中是否存在用户(而不是尝试创建新用户) )?谢谢!

2 个答案:

答案 0 :(得分:0)

您项目的所有权记录无效,因为它需要project_idnil表示新项目。您需要先创建项目或更改Ownership模型中的验证。

您可以通过检查所涉及模型的错误对象来看到这一点:

> prj.errors.full_messages
=> ["Ownerships is invalid"]
> prj.ownerships.first.errors.full_messages
=> ["Project can't be blank"]

答案 1 :(得分:0)

尝试将ownership课程的验证更改为

validates :user, presence: true
validates :project, presence: true

不确定验证实际关联(project)与id(project_id)之间的区别是否会产生影响,但值得尝试。也就是说,如果您从项目方创建关联(并且项目必须始终拥有用户而不是其他方式),那么您的业务规则就会发现您只有真正需要用户端无论如何都要验证。