I have made an application recently which has articles, etc, with a commenting/moderation system on top. There are one of three things that happen when a user leaves a comment.
The first is if they are a registered user and logged in via Devise, their comment is flagged with a status of '2' and gets published right away. If they are an anonymous user with a previously approved comment with a matching email address, comment gets status of '1' and gets put into a moderation queue for approval. And if the user is completely brand new and their email isn't in the system, that comment gets a status of '0' and an email is sent to their inbox to click on a link to approve their email. After any of this, an appropriate notice/flash message is displayed.
I have all this working fine, but did nearly all the logic and variable definition in the controller, making the create action very fat. In the interest of learning best practices and the convention of 'fat model, skinny controller,' I am trying to move what logic I can into the Comment model, particularly the portion that figures out if they're logged in or what. So hypothetically, something like this in the model...
attr_accessor :message
before_create :poster_type
def poster_type
if current_user
self.status = 2
self.message = 'Your comment has been posted.'
elsif Comment.find_by_mail(self.mail, :conditions => { :status => [1,2]}).present?
self.status = 1
self.message = 'Your comment has been sent for moderation.'
else
self.status = 0
self.message = 'This is a new email, please confirm...'
end
end
Problem is, you can't use Devise's current_user method (or others like user_signed_in?, etc) in the model, apparently. Every answer I have researched on this says unhelpfully that it isn't the business of the model to access current_user values, etc.
However, I don't exactly need to give the model a user's information (as I've seen all other threads trying to do), all I need the method in the model to figure out is simply whether they're logged in or not.
In addition, if you can't use current_user (or other user detecting methods) in the model, then you would have no other choice than to define all the logic in the controller, and isn't that bad practice as well? So if it's possible, how can I do this logic in the model? Or should I simply just leave the controller fat?
You cannot access the devise user or session from any model due to separation of layers. What you can do is send the the object to the model.
I've done something like your solution before and It was just a headache.
So in your create action.
def create
if current_user
@user.current_user(true)
end
end
Then just send true/false to a method on the user:
def current_user(current_user)
current_user
end
Then you can have a before_create
that checks if that is true.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With