开发者

Trying to use current_user where it is undefined

I have this call in my vote model:

 fires :vote_updated, :on => :update,
                   :actor => :user,
                   :secondary_subject => :video,
                   :if => lambda { |vote| ((vote.value == 1) || (vote.value == -1)) && (vote.video.user != current_user)}

In case you aren't familiar, it works with the timeline_fu plugin.

I do not want the call to be fired if the user who owns the voted up video is the current user. That is where this line comes in:

:if => lambda { |vote| ((vote.value == 1) || (vote.value == -1)) && (vote.video.user != current_user)}

However, I do not have access to current_user here. How do I get around this?

Here's the create method in my votes controller (there actually is no update method):

def create       
  @video = Video.find(params[:video_id])
  @vote = current_user.video_votes.find_or_create_by_video_id(@video.id)

  if @vote.value.nil?
    if params[:type] =开发者_开发问答= "up"
      @vote.value = 1
    else
      @vote.value = -1
    end
  elsif (params[:type] == "up" && @vote.value == 1) || (params[:type] == "down" && @vote.value == -1)
    @vote.value = 0
  elsif ((params[:type] == "up" && @vote.value == -1) || (params[:type] == "down" && @vote.value == 1)) || (@vote.value == 0)
    if params[:type] == "up"
      @vote.value = 1
    else
      @vote.value = -1
    end
  end  

  if @vote.save
    respond_to do |format|
      format.html { redirect_to @video }
      format.js
    end
  else
    respond_to do |format|
      format.html
      format.js
    end
  end  
end


I believe the right thing to do would be validating this in controller. I would create a before filter for this case

UPDATE:

Just as a quick example:

before_filter :valid_vote, :only => :update

def update
   @vote.update_attributes(params[:vote]) # or whatever
end
..

private

def valid_vote
   @vote = Vote.find params[:id]
   unless ( @vote.video.user.id != current_user.id )
      render :text => 'You can't vote for your own video', :status => 403
   end
end

So @vote is being declared and validated before your 'update' action is proccessed. If it's not valid then your 'update' action stays untouched

UPDATE 2 :

not sure how you'll like it, but you could also do as follows:

in your Vote model:

attr_accessor :skip_timeline

then use the concept with before filter, but do @vote.skip_timeline = true instead of rendering text

then the statement might look as follows:

:if => lambda { |vote| ((vote.value == 1) || (vote.value == -1)) && !vote.skip_timeline }

You could also move ((vote.value == 1) || (vote.value == -1)) to your before filter :

def valid_vote
   @vote = Vote.find params[:id]
   unless ( [1,-1].include? @vote.value && @vote.video.user.id != current_user.id )
       @vote.skip_timeline = true
   end
end

and

:if => lambda { |vote| !vote.skip_timeline }


You are getting this error because it's typically not recommended to access current_user (or session information) in your model. I am not all that familiar with the timeline_fu gem, so this answer isn't going to be the greatest answer you may get. I'm merely going to show you how to access current_user from any model.

First go to your application controller. You'll want to make a method that sets the current user. You need to call the method in the before filter.

before_filter :loadCurrentUser 

def loadCurrentUser
  User.currentUser = current_user
end

Then in your User model, you need to define 'currentUser'.

def self.currentUser
   Thread.currentUser[:user]
end

You don't necessarily have to declare the current_user in the application controller, but since it's a gem, I'm not sure if it has an easily accessible controller.

Edit: This way may be prone to problems, but I'm not entirely sure if you were asking how to make current_user available in models, or a completely different workaround so you do not have that problem... and reading the responses of the other answer, I'm thinking it's not what you were asking.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜