Ok so I have a few models that need to interact with each other - Blog, Post, and User. I''ll get their relationships out of the way: Blog has_many :posts has_and_belongs_to_many :users (by way of a join table, a blog can have many contributing users) Post belongs_to :blog belongs_to :user (the author of the post) User has_and_belongs_to_many :blogs (a user can contribute to many blogs) has_many :posts I''m running into a problem when validating posts; I want to ensure that the logged in user we find in the session is listed as a contributor to the blog they are trying to post to. I added some validation to my Post model, that appears to be failing when editing an existing post. Post creation, curiously, seems to pass the validation test. I should note that @user is a variable set by my ApplicationController using a before_filter. really sure what''s going on here, so any help is appreciated. I''m guessing the @user set by my app controller probably isn''t accessible by the Post class. Anyhow, here''s my Post model: class Post < ActiveRecord::Base belongs_to :blog belongs_to :user has_many :comments validate :user_can_contribute private def user_can_contribute if @user.nil? logger.info("@user hasn''t been set yet!") end if !blog.users.include?(@user) errors.add(:user, "You cannot contribute to this blog.") end end end -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Actually, I''m not so sure if post creation is passing the validation test either :) Sorry for being confusing. On Feb 27, 11:09 am, robo <chase.delanguille...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Ok so I have a few models that need to interact with each other - > Blog, Post, and User. I''ll get their relationships out of the way: > > Blog > has_many :posts > has_and_belongs_to_many :users (by way of a join table, a blog can > have many contributing users) > > Post > belongs_to :blog > belongs_to :user (the author of the post) > > User > has_and_belongs_to_many :blogs (a user can contribute to many blogs) > has_many :posts > > I''m running into a problem when validating posts; I want to ensure > that the logged in user we find in the session is listed as a > contributor to the blog they are trying to post to. I added some > validation to my Post model, that appears to be failing when editing > an existing post. Post creation, curiously, seems to pass the > validation test. > > I should note that @user is a variable set by my ApplicationController > using a before_filter. really sure what''s going on here, so any help > is appreciated. I''m guessing the @user set by my app controller > probably isn''t accessible by the Post class. > > Anyhow, here''s my Post model: > > class Post < ActiveRecord::Base > belongs_to :blog > belongs_to :user > has_many :comments > > validate :user_can_contribute > > private > def user_can_contribute > if @user.nil? > logger.info("@user hasn''t been set yet!") > end > > if !blog.users.include?(@user) > errors.add(:user, "You cannot contribute to this blog.") > end > end > end-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Colin Law
2010-Feb-27 17:14 UTC
Re: Model validation dependent upon session data being set?
On 27 February 2010 17:09, robo <chase.delanguillette-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Ok so I have a few models that need to interact with each other - > Blog, Post, and User. I''ll get their relationships out of the way: > > Blog > has_many :posts > has_and_belongs_to_many :users (by way of a join table, a blog can > have many contributing users) > > Post > belongs_to :blog > belongs_to :user (the author of the post) > > User > has_and_belongs_to_many :blogs (a user can contribute to many blogs) > has_many :posts > > > I''m running into a problem when validating posts; I want to ensure > that the logged in user we find in the session is listed as a > contributor to the blog they are trying to post to. I added some > validation to my Post model, that appears to be failing when editing > an existing post. Post creation, curiously, seems to pass the > validation test. > > I should note that @user is a variable set by my ApplicationController > using a before_filter. really sure what''s going on here, so any help > is appreciated. I''m guessing the @user set by my app controller > probably isn''t accessible by the Post class. > > Anyhow, here''s my Post model: > > class Post < ActiveRecord::Base > belongs_to :blog > belongs_to :user > has_many :comments > > validate :user_can_contribute > > private > def user_can_contribute > if @user.nil? > logger.info("@user hasn''t been set yet!") > end > > if !blog.users.include?(@user) > errors.add(:user, "You cannot contribute to this blog.") > end > end > endHave you tried using ruby-debug to break into the validation code and see what is happening? See the rails guide on debugging at http://guides.rubyonrails.org/ Colin -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Michael Pavling
2010-Feb-27 19:24 UTC
Re: Model validation dependent upon session data being set?
On 27 February 2010 17:09, robo <chase.delanguillette-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I should note that @user is a variable set by my ApplicationController > using a before_filter. really sure what''s going on here, so any help > is appreciated. I''m guessing the @user set by my app controller > probably isn''t accessible by the Post class.Yup - you''ve identified your problem perfectly... here''s a suggested solution: @user is a instance variable; that is, only available to the instance of a class (in this instance, the controller). So you can''t access it from an instance of a different class. So you need to create a method on your controller that will return the @user object. The convention for this method seems to be to call it "current_user". def current_user @user end Simple, huh? ;-) Now you can get rid of that before_filter call, and do the operation when/if somewhere calls "current_user" - so it''ll look more like this: def current_user @user ||= the_method_for_the_logic_that_works_out_the_logged_in_user end An other solution would be to use a wrapped-up plugin to do authentication (there are lots to choose from), which would take all you user/password management woes and deal with them for you (and most likely give you a "current_user" method!) HTH Michael -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Michael Pavling
2010-Feb-27 19:36 UTC
Re: Model validation dependent upon session data being set?
On 27 February 2010 19:24, Michael Pavling <pavling-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> So you need to create a method on your controller that will return the > @user object. The convention for this method seems to be to call it > "current_user". >*ahem* Of course... an instance of a model doesn''t have access to application_controller''s methods... I was getting carried away with myself. You will *also* need to pass this to the Post directly... so declare an "attr_writer :current_user" on your Post model, and in the controller, when you instanciate the Post, pass it the variable: post = Post.find(params[:post_id] # or whatever... post.current_user = current_user -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.
Hey, that did the trick. Thanks for that! On Feb 27, 1:36 pm, Michael Pavling <pavl...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On 27 February 2010 19:24, Michael Pavling <pavl...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > So you need to create a method on your controller that will return the > > @user object. The convention for this method seems to be to call it > > "current_user". > > *ahem* Of course... an instance of a model doesn''t have access to > application_controller''s methods... I was getting carried away with > myself. > You will *also* need to pass this to the Post directly... so declare > an "attr_writer :current_user" on your Post model, and in the > controller, when you instanciate the Post, pass it the variable: > > post = Post.find(params[:post_id] # or whatever... > post.current_user = current_user-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.