简体   繁体   中英

Combining params in Rails

Hi im doing a filter section for "players" on my app..

Im filtering by "position" at this moment, but i need to filter by "birthday.year" in database the birthday is complete 1900-00-00

I actually do a good research before but i can "mix" or "combine" my params.. the best answer i found was here (so its not a duplicate) Rails: combining optional params into a query

im a noob in Rails,so i will appreciate any help im just doing the integration of a design..

Here is my code but how can i use minyear, and maxyear to filter by position and age, for example..

thanks!!

def index
    @candidates = Player.order("created_at DESC")

    position = params[:position]
    minyear = params[:minyear]
    maxyear = params[:maxyear]


    if position == 'goalkeeper'
  @candidates = @candidates.where(position:'goalkeeper') 
 elsif position == 'cedefense'
  @candidates = @candidates.where(position:'cedefense') 
 elsif position == 'ridefense'
  @candidates = @candidates.where(position:'ridefense') 
 elsif position == 'ledefense'
  @candidates = @candidates.where(position:'ledefense') 
 elsif position == 'defmedium'
  @candidates = @candidates.where(position:'defmedium') 
 elsif position == 'ofemedium'
  @candidates = @candidates.where(position:'ofemedium') 
 elsif position == 'rimedium'
  @candidates = @candidates.where(position:'rimedium') 
 elsif position == 'lemedium'
  @candidates = @candidates.where(position:'lemedium') 
 elsif position == 'offensive'
  @candidates = @candidates.where(position:'offensive') 
 elsif position == 'scoach'
  @candidates = @candidates.where(position:'scoach') 
 elsif position == 'sprepf'
  @candidates = @candidates.where(position:'sprepf')                 
 else
  @candidates = Player.all
 end

After a lot of research i come up with this

 position = params[:position]
    minyear = params[:minyear]
    maxyear = params[:maxyear]

  if  params[:position].nil? 
  @candidates = Player.all
  elsif  !params[:position].nil? && params[:minyear].nil?
  @candidates = @candidates.where("position = ?", position) 
  elsif !params[:minyear].nil?
  @candidates = @candidates.where("position = ? and birthday = ?", position, minyear )                 
 else
  @candidates = Player.all
 end

The only problem now is that birthday as i said before has a full format, im just interested just in the year... how can i solve this?

thanks in advance

Nevermind it works like this

@candidates = @candidates.where("position = ? and birthday < ?", position, minyear )

Thanks to Alex D i ha this now,

@candidates = Player.scoped # for Rails 3
 if params[:position].present?
   @candidates = @candidates.where(position: position)
 end


 if year = params[:year]
   date = Date.new(year)
   # this will find all people whose birthday is within the given year
   # using YEAR(birthday) will likely cause a full table scan;
   #   it's better to use a range query
   @candidates = @candidates.where("birthday >= ? AND birthday <= ?", Date.new(minyear), Date.new(maxyear).end_of_year)
 end

First of all, you can improve your code if you know that Active Record's where and other similar methods are chainable:

 @candidates = Player.order('created_at DESC')
 # if you don't want to set a default order, you can use Player.scoped in Rails 3
 # I forget what it is for Rails 4. Maybe just Player.all.
 # In Rails 3, .all returns an Array, which doesn't allow you to chain additional
 #   where conditions, etc.
 if params[:position].present?
   @candidates = @candidates.where(position: position)
 end
 if params[:minyear].present?
   @candidates = @candidates.where(birthday: minyear)
 end

Now the second part: you actually want to match on the birthday year. There are a couple ways to do this, but this is the way which can benefit from database indexes if you have the right indexes in place:

 if year = params[:year]
   date = Date.new(year)
   # this will find all people whose birthday is within the given year
   # using YEAR(birthday) will likely cause a full table scan;
   #   it's better to use a range query
   @candidates = @candidates.where("birthday >= ? AND birthday <= ?", date, date.end_of_year)
 end

Since your param is called minyear , I'm guessing you may actually want all the people whose birthday is during the given year or later . In that case:

 @candidates = @candidates.where("birthday >= ?", Date.new(year))

Or if it's minyear and maxyear :

 @candidates = @candidates.where("birthday >= ? AND birthday <= ?", Date.new(minyear), Date.new(maxyear).end_of_year)
@candidates = @candidates.where("position = ? and year(birthday) < ?", position, minyear )

尝试一下,这将符合您的目的。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM