Validate ActiveRecord models have same association / group












0















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.










share|improve this question























  • can you add the error message please?

    – Shiko
    Nov 15 '18 at 20:14
















0















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.










share|improve this question























  • can you add the error message please?

    – Shiko
    Nov 15 '18 at 20:14














0












0








0








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.










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 '18 at 19:50









robinvdvleutenrobinvdvleuten

539813




539813













  • 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





can you add the error message please?

– Shiko
Nov 15 '18 at 20:14












1 Answer
1






active

oldest

votes


















1














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.






share|improve this answer
























  • 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











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
});


}
});














draft saved

draft discarded


















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









1














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.






share|improve this answer
























  • 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
















1














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.






share|improve this answer
























  • 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














1












1








1







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.






share|improve this answer













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.







share|improve this answer












share|improve this answer



share|improve this answer










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



















  • 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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Florida Star v. B. J. F.

Danny Elfman

Retrieve a Users Dashboard in Tumblr with R and TumblR. Oauth Issues