So i have:
class MainSite
def self.matches?(request)
request.subdomain.blank? || request.subdomain == 'www'
request.subdomain.blank? || request.subdomain == 'limitless-tor-hello' && 'rocky-depths-buhbye'
end
end
But routing only works for limitless and not rocky.. Is it possible to have both of them work? I tried using the && operator which obviously didn't work.
Please help!
Thanks!
Try this:
class MainSite
def self.matches?(request)
request.subdomain.blank? || request.subdomain == 'www'
request.subdomain.blank? ||
request.subdomain == 'limitless-tor-hello' ||
request.subdomain == 'rocky-depths-buhbye'
end
end
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 get a warning every time I start my server that I have string literals in my conditions. What does this mean, and how can I improve my code to fix this and stop getting the warning?
def partner_cars
if self.role == 'Garage Employee' || self.role == 'Garage Manager'
self.cars
elsif self.role == 'Company Employee' || 'Company Manager'
self.company.cars
else
nil
end
end
def partner_users
if self.role == 'Garage Employee' || self.role == 'Garage Manager'
allowed_users = self.users
elsif self.role == 'Company Employee' || 'Company Manager'
allowed_users = self.company.users
else
allowed_users = nil
end
allowed_users.uniq
end
Any help on how to refactor this code would be much appreciated, thanks!
The error comes from the line elsif self.role == 'Company Employee' || 'Company Manager'. Instead, it should be elsif self.role == 'Company Employee' || self.role == 'Company Manager'.
However, I would refactor your code to use case statements like this:
def partner_cars
case role
when 'Garage Employee', 'Garage Manager' then cars
when 'Company Employee', 'Company Manager' then company.cars
end
end
def partner_users
allowed_users =
case role
when 'Garage Employee', 'Garage Manager' then users
when 'Company Employee', 'Company Manager' then company.users
end
allowed_users.try(:uniq)
end
Without knowing your data structure, its hard to suggest a refactoring approach.
def partner_cars
if garage_roles.include?(self.role)
...some code
elsif employee_roles.include?(self.role)
..some code
end
end
private
def garage_roles
['Garage Employee', 'Garage Manager']
end
Even better would be to set up these methods in your role model.
class Role
def works_for_garage?
title == 'Garage Manager' || 'Garage Employee'
end
end
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.