This is somehow related to my last question about unsaved objects , but now we are talking about the specific problem of using rails.
Models that I have:
class User < ActiveRecord::Base has_many :project_participations has_many :projects, through: :project_participations, inverse_of: :users end class ProjectParticipation < ActiveRecord::Base belongs_to :user belongs_to :project enum role: { member: 0, manager: 1 } end class Project < ActiveRecord::Base has_many :project_participations has_many :users, through: :project_participations, inverse_of: :projects accepts_nested_attributes_for :project_participations end
In these models, when I create a new project, I can do it in the form ( fields_for , etc.), and then I can call update_attributes in the controller. Therefore, if I have users in the database, I can do this:
u = Users.create
This works fine until I want to do something with the users project. For example, I want to add confirmation that there must be at least one user for the project:
class Project < ActiveRecord::Base ... validates :users, presence: true
Now it gives:
u = Users.create p = Project.new p.update_attributes(project_participations_attributes: [{user_id: u.id, role: 1}]) => false p.errors => #<ActiveModel::Errors:... @base=#<Project id: nil>, @messages={:users=>["can't be blank"]}> p.users => #<ActiveRecord::Associations::CollectionProxy []> p.project_participations => #<ActiveRecord::Associations::CollectionProxy [#<ProjectParticipation id: nil, user_id: 1, project_id: nil>]>
So, on unsaved projects .users empty. This already bothers me (see my last question about unsaved objects ). But in this case, of course, I can now get around this by doing validates :project_participations, presence: true instead of validates :users, presence: true , and that should mean the same thing.
But that would mean that I should never use the .users method (in any helper, model, view, ...), if I'm not sure that I am working with a saved object. What actually makes the .users method unusable (for example, when checking for the presence of a user).
If I call update_attributes as follows, checks are performed and saved:
p.update_attributes(users: [u])
In doing so, he creates project_participation himself, so p.users works as expected. But here I can not set data such as role for project_participation this user.
So my questions are: can I make the .users method work regardless of whether the object is saved (I think not)? But how can I add users to an unsaved project as a manager / member and work with an unsaved project?
I hope my problem is clear.