it also shows the link for order where received_by_admin is True.
if order.payment_status == 'Paid' && order.received_by_admin != 'true'
link_to "Payment Received", "orders/#{order.id}/?payment_status=Paid", class: "member_link", method: :put
end
probably because received_by_admin is a boolean? So
order.payment_status == 'Paid' && order.received_by_admin != true
or simpler
order.payment_status == 'Paid' && !order.received_by_admin
the point here is that true != 'true'
Related
I have a method in my rails app.
def current_user_can_edit?(model)
user_signed_in? && (
model.user == current_user ||
(model.try(:post).present? && model.post.user == current_user)
)
end
The method is needed to check the possibility of editing the model. There are posts and events in my app. I would like to dynamically substitute a post or event for a choice, instead of a static post.
How can I write a method correctly so as not to make a lot of conditions? Like, for example, here:
def current_user_can_edit?(model, action)
if action.class.to_s == 'Post':
user_signed_in? && (
model.user == current_user ||
(model.try(:post).present? && model.post.user == current_user)
)
elsif action.class.to_s == 'Event':
user_signed_in? && (
model.user == current_user ||
(model.try(:event).present? && model.event.user == current_user)
)
end
end
In your method's logic, the expression:
model.try(:post).present? && model.post.user == current_user
can be combined by chaining two try calls:
model.try(:post).try(:user) == current_user
Now you can replace :post by a calculated value:
model.try(action.class.to_s.downcase).try(:user) == current_user
Whole code:
def current_user_can_edit?(model, action)
user_signed_in? && (
model.user == current_user ||
model.try(action.class.to_s.downcase).try(:user) == current_user
)
end
You could also use some guard clauses:
def current_user_can_edit?(model, action)
return unless user_signed_in?
return true if model.user == current_user
model.try(action.class.to_s.downcase).try(:user) == current_user
end
I'm assuming that action.class.to_s returns "Post". The code would of course be easier if you would pass :post as the method's second parameter.
I've got a page with several URL parameters that are not model attributes that I use for sorting and filtering. Currently I'm trying to validate them in the controller like this question however am having trouble validating that a parameter is in an expected set of values.
before_filter :validate_params, :only => :index
def validate_params
if !params[:type] = 'any' || !params[:type] = 'up' || !params[:type] = 'down'
params[:type] = 'any'
end
end
In this case the value is always 'any' even if the parameter is 'up' or 'down'.
You should comapre it using == or != and not =
= is for assignment and == and != are for comparison
def validate_params
if params[:type] != 'any' || !params[:type] != 'up' || !params[:type] != 'down'
params[:type] = 'any'
end
end
OR
!['any', 'up', 'down'].include?(params[:type])
well if you think about it if params[:type] == 'up' then it is not params[:type] == 'down' so it will always set to any because you are using ||. try using && instead
if !params[:type] == 'any' && !params[:type] == 'up' && !params[:type] == 'down'
if you want to set a params[:type] that is different that any, up ordown and also use ==
The condition may look like this,
before_filter :validate_params, :only => :index
def validate_params
if params[:type] != 'any' || params[:type] != 'up' || params[:type] != 'down'
params[:type] = 'any'
end
end
After detect the browser page will we redirecte.
def detect_browser
redirect_to "privacy" if browser.ie6? || browser.ie7? || browser.firefox?
end
Causes the infinite loops.?
Try something like this:
def detect_browser
if(browser.ie6? || browser.ie7? || browser.firefox? ) &&
params[:controller] != "privacy", params[:action] != "show"
redirect_to "privacy"
end
end
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.
%div{:class => [#item.type, #item == #sortcol && [:sort, #sortdir]] } Contents
could render as any of:
<div class="numeric sort ascending">Contents</div>
<div class="numeric">Contents</div>
<div class="sort descending">Contents</div>
<div>Contents</div>
I don't really understand the #sortcol && [:sort, #sortdir] part of this snippet.
This relies on operator precedence. So it is evaluated like this:
#item == #sortcol is either true or false.
when false
&& returns false because the other part is not evaluated
hence the code reduces to :class => [#item.type]
when true
&& returns the second part of the expression. In this case the array [:sort, #sortdir]
HAML automatically flattens the array before rendering thus it's equivalent to :class => [#item.type, :sort, #sortdir]
[#item.type, #item == #sortcol && [:sort, #sortdir]]
=>
# if #item.type is blank, so class is still empty
# if #item.type is "numeric" class is "numeric"
class = #item.type
# if #item equal #sortcol
# class will append "sort" and #sortdir if it is not empty.
if #item == #sortcol
class += "sort"
class += #sortdir
end
This construction #item == #sortcol && [:sort, #sortdir] will return [:sort, #sortdir] only if #item == #sortcol is true