Validate ActiveRecord models have same association / group
So I am trying to get my head around a custom validation on two ActiveRecord models. The application I am working on contains 3 models; a note, a writer and a notebook. Whenever I create a note through a form, I want to validate that it has the exact same notebook as the writer is currently allowed to work on when created or updated.
The models look really simplified like this;
class Notebook < ApplicationRecord
has_many :notes
has_many :writers
end
class Writer < ApplicationRecord
has_many :notes
belongs_to: notebook
end
class Note < ApplicationRecord
belongs_to: writer
belongs_to: notebook
end
So whenever I do something like this;
another_notebook = Notebook.new
writer = Writer.new
note = Note.new(writer: writer, notebook: another_notebook)
note.save!
A validation error is thrown as the writer and the notebook do not have an association with each other.
ruby-on-rails ruby activerecord rails-activerecord
add a comment |
So I am trying to get my head around a custom validation on two ActiveRecord models. The application I am working on contains 3 models; a note, a writer and a notebook. Whenever I create a note through a form, I want to validate that it has the exact same notebook as the writer is currently allowed to work on when created or updated.
The models look really simplified like this;
class Notebook < ApplicationRecord
has_many :notes
has_many :writers
end
class Writer < ApplicationRecord
has_many :notes
belongs_to: notebook
end
class Note < ApplicationRecord
belongs_to: writer
belongs_to: notebook
end
So whenever I do something like this;
another_notebook = Notebook.new
writer = Writer.new
note = Note.new(writer: writer, notebook: another_notebook)
note.save!
A validation error is thrown as the writer and the notebook do not have an association with each other.
ruby-on-rails ruby activerecord rails-activerecord
can you add the error message please?
– Shiko
Nov 15 '18 at 20:14
add a comment |
So I am trying to get my head around a custom validation on two ActiveRecord models. The application I am working on contains 3 models; a note, a writer and a notebook. Whenever I create a note through a form, I want to validate that it has the exact same notebook as the writer is currently allowed to work on when created or updated.
The models look really simplified like this;
class Notebook < ApplicationRecord
has_many :notes
has_many :writers
end
class Writer < ApplicationRecord
has_many :notes
belongs_to: notebook
end
class Note < ApplicationRecord
belongs_to: writer
belongs_to: notebook
end
So whenever I do something like this;
another_notebook = Notebook.new
writer = Writer.new
note = Note.new(writer: writer, notebook: another_notebook)
note.save!
A validation error is thrown as the writer and the notebook do not have an association with each other.
ruby-on-rails ruby activerecord rails-activerecord
So I am trying to get my head around a custom validation on two ActiveRecord models. The application I am working on contains 3 models; a note, a writer and a notebook. Whenever I create a note through a form, I want to validate that it has the exact same notebook as the writer is currently allowed to work on when created or updated.
The models look really simplified like this;
class Notebook < ApplicationRecord
has_many :notes
has_many :writers
end
class Writer < ApplicationRecord
has_many :notes
belongs_to: notebook
end
class Note < ApplicationRecord
belongs_to: writer
belongs_to: notebook
end
So whenever I do something like this;
another_notebook = Notebook.new
writer = Writer.new
note = Note.new(writer: writer, notebook: another_notebook)
note.save!
A validation error is thrown as the writer and the notebook do not have an association with each other.
ruby-on-rails ruby activerecord rails-activerecord
ruby-on-rails ruby activerecord rails-activerecord
asked Nov 15 '18 at 19:50
robinvdvleutenrobinvdvleuten
539813
539813
can you add the error message please?
– Shiko
Nov 15 '18 at 20:14
add a comment |
can you add the error message please?
– Shiko
Nov 15 '18 at 20:14
can you add the error message please?
– Shiko
Nov 15 '18 at 20:14
can you add the error message please?
– Shiko
Nov 15 '18 at 20:14
add a comment |
1 Answer
1
active
oldest
votes
First just start off by creating indirect assocations:
class Notebook < ApplicationRecord
has_many :notes
has_many :writers, through: :notes
end
class Note < ApplicationRecord
belongs_to: writer
belongs_to: notebook
end
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
# ...
end
This creates a many-to-many association between Notebook and Writer.
If you then want to add rule that the writer
can only create notes in a specific notebook:
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
belongs_to :current_notebook, class: 'Notebook'
end
class Note < ApplicationRecord
# ...
validate :is_current_notebook
def is_current_notebook
unless notebook == writer.current_notebook
errors.add(:notebook, 'is not valid.')
end
end
end
However I would consider if this actually is a good fit for a model validation as it seems like more of a authorization issue that should be handled by CanCanCan or Pundit and not an issue of bad user input which is what validations should handle.
Thanks Max for the answer! Exactly what I was looking for! I can see how you say that it is more of an authorization issue, but I would like to constraint that people cannot create different notes for different notebooks by changing the parameters in the URL (/:notebook_id/notes/:note_id/edit).
– robinvdvleuten
Nov 17 '18 at 17:32
They should not be able to do that anyways if you set the controller up properly.
– max
Nov 17 '18 at 17:58
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53326948%2fvalidate-activerecord-models-have-same-association-group%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
First just start off by creating indirect assocations:
class Notebook < ApplicationRecord
has_many :notes
has_many :writers, through: :notes
end
class Note < ApplicationRecord
belongs_to: writer
belongs_to: notebook
end
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
# ...
end
This creates a many-to-many association between Notebook and Writer.
If you then want to add rule that the writer
can only create notes in a specific notebook:
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
belongs_to :current_notebook, class: 'Notebook'
end
class Note < ApplicationRecord
# ...
validate :is_current_notebook
def is_current_notebook
unless notebook == writer.current_notebook
errors.add(:notebook, 'is not valid.')
end
end
end
However I would consider if this actually is a good fit for a model validation as it seems like more of a authorization issue that should be handled by CanCanCan or Pundit and not an issue of bad user input which is what validations should handle.
Thanks Max for the answer! Exactly what I was looking for! I can see how you say that it is more of an authorization issue, but I would like to constraint that people cannot create different notes for different notebooks by changing the parameters in the URL (/:notebook_id/notes/:note_id/edit).
– robinvdvleuten
Nov 17 '18 at 17:32
They should not be able to do that anyways if you set the controller up properly.
– max
Nov 17 '18 at 17:58
add a comment |
First just start off by creating indirect assocations:
class Notebook < ApplicationRecord
has_many :notes
has_many :writers, through: :notes
end
class Note < ApplicationRecord
belongs_to: writer
belongs_to: notebook
end
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
# ...
end
This creates a many-to-many association between Notebook and Writer.
If you then want to add rule that the writer
can only create notes in a specific notebook:
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
belongs_to :current_notebook, class: 'Notebook'
end
class Note < ApplicationRecord
# ...
validate :is_current_notebook
def is_current_notebook
unless notebook == writer.current_notebook
errors.add(:notebook, 'is not valid.')
end
end
end
However I would consider if this actually is a good fit for a model validation as it seems like more of a authorization issue that should be handled by CanCanCan or Pundit and not an issue of bad user input which is what validations should handle.
Thanks Max for the answer! Exactly what I was looking for! I can see how you say that it is more of an authorization issue, but I would like to constraint that people cannot create different notes for different notebooks by changing the parameters in the URL (/:notebook_id/notes/:note_id/edit).
– robinvdvleuten
Nov 17 '18 at 17:32
They should not be able to do that anyways if you set the controller up properly.
– max
Nov 17 '18 at 17:58
add a comment |
First just start off by creating indirect assocations:
class Notebook < ApplicationRecord
has_many :notes
has_many :writers, through: :notes
end
class Note < ApplicationRecord
belongs_to: writer
belongs_to: notebook
end
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
# ...
end
This creates a many-to-many association between Notebook and Writer.
If you then want to add rule that the writer
can only create notes in a specific notebook:
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
belongs_to :current_notebook, class: 'Notebook'
end
class Note < ApplicationRecord
# ...
validate :is_current_notebook
def is_current_notebook
unless notebook == writer.current_notebook
errors.add(:notebook, 'is not valid.')
end
end
end
However I would consider if this actually is a good fit for a model validation as it seems like more of a authorization issue that should be handled by CanCanCan or Pundit and not an issue of bad user input which is what validations should handle.
First just start off by creating indirect assocations:
class Notebook < ApplicationRecord
has_many :notes
has_many :writers, through: :notes
end
class Note < ApplicationRecord
belongs_to: writer
belongs_to: notebook
end
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
# ...
end
This creates a many-to-many association between Notebook and Writer.
If you then want to add rule that the writer
can only create notes in a specific notebook:
class Writer < ApplicationRecord
has_many :notes
has_many :notebooks, through: :notes
belongs_to :current_notebook, class: 'Notebook'
end
class Note < ApplicationRecord
# ...
validate :is_current_notebook
def is_current_notebook
unless notebook == writer.current_notebook
errors.add(:notebook, 'is not valid.')
end
end
end
However I would consider if this actually is a good fit for a model validation as it seems like more of a authorization issue that should be handled by CanCanCan or Pundit and not an issue of bad user input which is what validations should handle.
answered Nov 16 '18 at 13:15
maxmax
46.5k1060105
46.5k1060105
Thanks Max for the answer! Exactly what I was looking for! I can see how you say that it is more of an authorization issue, but I would like to constraint that people cannot create different notes for different notebooks by changing the parameters in the URL (/:notebook_id/notes/:note_id/edit).
– robinvdvleuten
Nov 17 '18 at 17:32
They should not be able to do that anyways if you set the controller up properly.
– max
Nov 17 '18 at 17:58
add a comment |
Thanks Max for the answer! Exactly what I was looking for! I can see how you say that it is more of an authorization issue, but I would like to constraint that people cannot create different notes for different notebooks by changing the parameters in the URL (/:notebook_id/notes/:note_id/edit).
– robinvdvleuten
Nov 17 '18 at 17:32
They should not be able to do that anyways if you set the controller up properly.
– max
Nov 17 '18 at 17:58
Thanks Max for the answer! Exactly what I was looking for! I can see how you say that it is more of an authorization issue, but I would like to constraint that people cannot create different notes for different notebooks by changing the parameters in the URL (/:notebook_id/notes/:note_id/edit).
– robinvdvleuten
Nov 17 '18 at 17:32
Thanks Max for the answer! Exactly what I was looking for! I can see how you say that it is more of an authorization issue, but I would like to constraint that people cannot create different notes for different notebooks by changing the parameters in the URL (/:notebook_id/notes/:note_id/edit).
– robinvdvleuten
Nov 17 '18 at 17:32
They should not be able to do that anyways if you set the controller up properly.
– max
Nov 17 '18 at 17:58
They should not be able to do that anyways if you set the controller up properly.
– max
Nov 17 '18 at 17:58
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53326948%2fvalidate-activerecord-models-have-same-association-group%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
can you add the error message please?
– Shiko
Nov 15 '18 at 20:14