SlideShare una empresa de Scribd logo
1 de 58
Descargar para leer sin conexión
WTF ORIENTED PROGRAMMING
by @AkitaOnRails
$('a').click(function(){	
  
	
  	
  	
  	
  window.location	
  =	
  $(a).attr('href');	
  
})
project_id	
  =	
  @user.project	
  ==	
  nil	
  ?	
  nil	
  :	
  @user.project.id
project_id	
  =	
  @user.project	
  ==	
  nil	
  ?	
  nil	
  :	
  @user.project.id
project_id	
  =	
  @user.try(:project).try(:id)
@politician	
  =	
  Politician.where(name:	
  "Terminator").first	
  
puts	
  @politician.try(:studio).try(:name)
@politician	
  =	
  Politician.where(name:	
  "Terminator").first	
  
puts	
  @politician.try(:studio).try(:name)
LAW OF DEMETER
@politician	
  =	
  Politician.where(name:	
  "Terminator").first	
  
puts	
  @politician.try(:studio).try(:name)
LAW OF DEMETER
class	
  Politician	
  
	
  	
  delegate	
  :name,	
  to:	
  :studio,	
  
	
  	
  	
  	
  prefix:	
  true,	
  allow_nil:	
  true	
  
	
  	
  #	
  ...	
  
end	
  
@politician.studio.name
class	
  Politician	
  
	
  	
  delegate	
  :name,	
  to:	
  :studio,	
  
	
  	
  	
  	
  prefix:	
  true,	
  allow_nil:	
  true	
  
	
  	
  #	
  ...	
  
end	
  
@politician.studio.name@politician.studio_name
class	
  Politician	
  
	
  	
  delegate	
  :name,	
  to:	
  :studio,	
  
	
  	
  	
  	
  prefix:	
  true,	
  allow_nil:	
  true	
  
	
  	
  #	
  ...	
  
end	
  
@politician.studio.name@politician.studio_name
array	
  =	
  []	
  
list.each	
  do	
  |state|	
  
	
  	
  array	
  <<	
  [state.name,	
  state.acronym]	
  
end	
  
array
array	
  =	
  []	
  
list.each	
  do	
  |state|	
  
	
  	
  array	
  <<	
  [state.name,	
  state.acronym]	
  
end	
  
array
for	
  state	
  in	
  list
array	
  =	
  []	
  
list.each	
  do	
  |state|	
  
	
  	
  array	
  <<	
  [state.name,	
  state.acronym]	
  
end	
  
array
list.map	
  {	
  |state|	
  [state.name,	
  state.acronym]	
  }
for	
  state	
  in	
  list
array	
  =	
  []	
  
list.each	
  do	
  |state|	
  
	
  	
  if	
  state.name	
  =~	
  /^S/	
  
	
  	
  	
  	
  array	
  <<	
  [state.name,	
  state.acronym]	
  
	
  	
  end	
  
end	
  
array
array	
  =	
  []	
  
list.each	
  do	
  |state|	
  
	
  	
  if	
  state.name	
  =~	
  /^S/	
  
	
  	
  	
  	
  array	
  <<	
  [state.name,	
  state.acronym]	
  
	
  	
  end	
  
end	
  
array
list.	
  
	
  	
  select	
  {	
  |state|	
  state.name	
  =~	
  /^S/	
  }.	
  
	
  	
  map	
  {	
  |state|	
  [state.name,	
  state.acronym]	
  }
def	
  formatdate(d)	
  
	
  	
  	
  	
  months	
  =	
  Hash.new	
  
	
  	
  	
  	
  months["Jan"]	
  =	
  "janeiro"	
  
	
  	
  	
  	
  months["Feb"]	
  =	
  "fevereiro"	
  
	
  	
  	
  	
  #	
  ...	
  
	
  	
  	
  	
  months["Dec"]	
  =	
  "dezembro"	
  
	
  	
  
	
  	
  	
  	
  weeks	
  =	
  Hash.new	
  
	
  	
  	
  	
  weeks["Sun"]	
  =	
  "Domingo"	
  
	
  	
  	
  	
  #	
  ...	
  
	
  	
  	
  	
  weeks["Fri"]	
  =	
  "Sexta"	
  
	
  	
  	
  	
  weeks["Sat"]	
  =	
  "Sábado"	
  
	
  	
  	
  	
  	
  
	
  	
  	
  	
  return	
  weeks[d.strftime("%a")]+",	
  "+d.strftime("%d")+"	
  de	
  "+months[d.strftime("%b")]	
  
end
def	
  formatdate(d)	
  
	
  	
  	
  	
  months	
  =	
  Hash.new	
  
	
  	
  	
  	
  months["Jan"]	
  =	
  "janeiro"	
  
	
  	
  	
  	
  months["Feb"]	
  =	
  "fevereiro"	
  
	
  	
  	
  	
  #	
  ...	
  
	
  	
  	
  	
  months["Dec"]	
  =	
  "dezembro"	
  
	
  	
  
	
  	
  	
  	
  weeks	
  =	
  Hash.new	
  
	
  	
  	
  	
  weeks["Sun"]	
  =	
  "Domingo"	
  
	
  	
  	
  	
  #	
  ...	
  
	
  	
  	
  	
  weeks["Fri"]	
  =	
  "Sexta"	
  
	
  	
  	
  	
  weeks["Sat"]	
  =	
  "Sábado"	
  
	
  	
  	
  	
  	
  
	
  	
  	
  	
  return	
  weeks[d.strftime("%a")]+",	
  "+d.strftime("%d")+"	
  de	
  "+months[d.strftime("%b")]	
  
end
#	
  config/locales/pt-­‐BR.yml	
  
pt-­‐BR:	
  
	
  	
  time:	
  
	
  	
  	
  	
  formats:	
  
	
  	
  	
  	
  	
  	
  short_wday:	
  "%a,	
  %d	
  de	
  %B”	
  
d.to_s(:short_wday)
.row	
  
	
  	
  .wrap-­‐select	
  
	
  	
  	
  	
  select.payment-­‐select	
  
	
  	
  	
  	
  	
  	
  -­‐	
  if	
  @payment_type	
  ==	
  'pagamento'	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.card-­‐credit[value="pagamento"	
  data-­‐foo="card-­‐credit"	
  selected]	
  Pagamento	
  
	
  	
  	
  	
  	
  	
  -­‐	
  else	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.card-­‐credit	
  value="pagamento"	
  data-­‐foo="card-­‐credit"	
  Pagamento	
  
	
  	
  	
  	
  	
  	
  -­‐	
  if	
  @payment_type.include?	
  'cartao'	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.card-­‐credit[value="cartao"	
  data-­‐foo="card-­‐credit"	
  selected]	
  Cartão	
  
	
  	
  	
  	
  	
  	
  -­‐	
  else	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.card-­‐credit	
  value="cartao"	
  data-­‐foo="card-­‐credit"	
  Cartão	
  
	
  	
  	
  	
  	
  	
  -­‐	
  if	
  @payment_type	
  ==	
  'dinheiro'	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.cash[value="dinheiro"	
  data-­‐foo="cash"	
  selected]	
  Dinheiro	
  
	
  	
  	
  	
  	
  	
  -­‐	
  else	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.cash	
  value="dinheiro"	
  data-­‐foo="cash"	
  Dinheiro	
  
	
  	
  	
  	
  	
  	
  -­‐	
  if	
  @payment_type	
  ==	
  'boleto'	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.banking-­‐billet[value="boleto"	
  data-­‐foo="banking-­‐billet"	
  selected]	
  Boleto	
  
	
  	
  	
  	
  	
  	
  -­‐	
  else	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.banking-­‐billet	
  value="boleto"	
  data-­‐foo="banking-­‐billet"	
  Boleto
.row	
  
	
  	
  .wrap-­‐select	
  
	
  	
  	
  	
  select.payment-­‐select	
  
	
  	
  	
  	
  	
  	
  -­‐	
  if	
  @payment_type	
  ==	
  'pagamento'	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.card-­‐credit[value="pagamento"	
  data-­‐foo="card-­‐credit"	
  selected]	
  Pagamento	
  
	
  	
  	
  	
  	
  	
  -­‐	
  else	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.card-­‐credit	
  value="pagamento"	
  data-­‐foo="card-­‐credit"	
  Pagamento	
  
	
  	
  	
  	
  	
  	
  -­‐	
  if	
  @payment_type.include?	
  'cartao'	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.card-­‐credit[value="cartao"	
  data-­‐foo="card-­‐credit"	
  selected]	
  Cartão	
  
	
  	
  	
  	
  	
  	
  -­‐	
  else	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.card-­‐credit	
  value="cartao"	
  data-­‐foo="card-­‐credit"	
  Cartão	
  
	
  	
  	
  	
  	
  	
  -­‐	
  if	
  @payment_type	
  ==	
  'dinheiro'	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.cash[value="dinheiro"	
  data-­‐foo="cash"	
  selected]	
  Dinheiro	
  
	
  	
  	
  	
  	
  	
  -­‐	
  else	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.cash	
  value="dinheiro"	
  data-­‐foo="cash"	
  Dinheiro	
  
	
  	
  	
  	
  	
  	
  -­‐	
  if	
  @payment_type	
  ==	
  'boleto'	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.banking-­‐billet[value="boleto"	
  data-­‐foo="banking-­‐billet"	
  selected]	
  Boleto	
  
	
  	
  	
  	
  	
  	
  -­‐	
  else	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select.banking-­‐billet	
  value="boleto"	
  data-­‐foo="banking-­‐billet"	
  Boleto
.row	
  
	
  	
  .wrap-­‐select	
  
	
  	
  	
  	
  select.payment-­‐select	
  
	
  	
  	
  	
  	
  	
  -­‐	
  pc	
  =	
  %w(card-­‐credit	
  card-­‐credit	
  cash	
  banking-­‐billet)	
  
	
  	
  	
  	
  	
  	
  -­‐	
  %w(pagamento	
  cartao	
  dinheiro	
  boleto).each_with_index	
  do	
  |i,	
  ptype|	
  
	
  	
  	
  	
  	
  	
  	
  	
  option.icons-­‐select[class=pc[i]	
  value=ptype	
  data-­‐foo=pc[i]	
  selected=(@payment_type==ptype)]	
  I18n.t(ptype)
<?php	
  if	
  (LANGUAGE	
  ==	
  'en')	
  {	
  ?>	
  <body	
  class="en">	
  <?php	
  }	
  ?>	
  
<?php	
  if	
  (LANGUAGE	
  ==	
  'pt')	
  {	
  ?>	
  <body	
  class="pt">	
  <?php	
  }	
  ?>	
  
<?php	
  if	
  (LANGUAGE	
  ==	
  'mx')	
  {	
  ?>	
  <body	
  class="mx">	
  <?php	
  }	
  ?>	
  
<?php	
  if	
  (LANGUAGE	
  ==	
  'kp')	
  {	
  ?>	
  <body	
  class="kp">	
  <?php	
  }	
  ?>
<?php	
  if	
  (LANGUAGE	
  ==	
  'en')	
  {	
  ?>	
  <body	
  class="en">	
  <?php	
  }	
  ?>	
  
<?php	
  if	
  (LANGUAGE	
  ==	
  'pt')	
  {	
  ?>	
  <body	
  class="pt">	
  <?php	
  }	
  ?>	
  
<?php	
  if	
  (LANGUAGE	
  ==	
  'mx')	
  {	
  ?>	
  <body	
  class="mx">	
  <?php	
  }	
  ?>	
  
<?php	
  if	
  (LANGUAGE	
  ==	
  'kp')	
  {	
  ?>	
  <body	
  class="kp">	
  <?php	
  }	
  ?>
<body	
  class="<?php	
  LANGUAGE	
  ?>">
address	
  =	
  ((!client.street.to_s.nil?)?	
  client.street.to_s	
  :	
  "")	
  +	
  	
  
((!client.number.to_s.nil?)?	
  "	
  Nº	
  "	
  +	
  client.number.to_s	
  :	
  "")	
  +	
  "	
  "	
  +	
  	
  
((!client.city.to_s.nil?)?	
  client.city.to_s	
  :	
  "")	
  +	
  	
  
((!client.zip.to_s.nil?)?	
  "	
  -­‐	
  CEP:	
  "	
  +	
  client.zip.to_s	
  :	
  "")
address	
  =	
  ((!client.street.to_s.nil?)?	
  client.street.to_s	
  :	
  "")	
  +	
  	
  
((!client.number.to_s.nil?)?	
  "	
  Nº	
  "	
  +	
  client.number.to_s	
  :	
  "")	
  +	
  "	
  "	
  +	
  	
  
((!client.city.to_s.nil?)?	
  client.city.to_s	
  :	
  "")	
  +	
  	
  
((!client.zip.to_s.nil?)?	
  "	
  -­‐	
  CEP:	
  "	
  +	
  client.zip.to_s	
  :	
  "")
address	
  =	
  "#{client.street}	
  Nº	
  #{client.number}	
  #{client.city}	
  -­‐	
  CEP:	
  #{client.zip}"
address	
  =	
  ((!client.street.to_s.nil?)?	
  client.street.to_s	
  :	
  "")	
  +	
  	
  
((!client.number.to_s.nil?)?	
  "	
  Nº	
  "	
  +	
  client.number.to_s	
  :	
  "")	
  +	
  "	
  "	
  +	
  	
  
((!client.city.to_s.nil?)?	
  client.city.to_s	
  :	
  "")	
  +	
  	
  
((!client.zip.to_s.nil?)?	
  "	
  -­‐	
  CEP:	
  "	
  +	
  client.zip.to_s	
  :	
  "")
address	
  =	
  "#{client.street}	
  Nº	
  #{client.number}	
  #{client.city}	
  -­‐	
  CEP:	
  #{client.zip}"
address	
  =	
  "%s	
  Nº	
  %s	
  %s	
  -­‐	
  CEP:	
  %s"	
  %	
  [client.street,	
  client.number,	
  client.city,	
  client.zip]
address	
  =	
  ((!client.street.to_s.nil?)?	
  client.street.to_s	
  :	
  "")	
  +	
  	
  
((!client.number.to_s.nil?)?	
  "	
  Nº	
  "	
  +	
  client.number.to_s	
  :	
  "")	
  +	
  "	
  "	
  +	
  	
  
((!client.city.to_s.nil?)?	
  client.city.to_s	
  :	
  "")	
  +	
  	
  
((!client.zip.to_s.nil?)?	
  "	
  -­‐	
  CEP:	
  "	
  +	
  client.zip.to_s	
  :	
  "")
address	
  =	
  "#{client.street}	
  Nº	
  #{client.number}	
  #{client.city}	
  -­‐	
  CEP:	
  #{client.zip}"
address	
  =	
  "%s	
  Nº	
  %s	
  %s	
  -­‐	
  CEP:	
  %s"	
  %	
  [client.street,	
  client.number,	
  client.city,	
  client.zip]
class	
  ClientDecorator	
  
	
  	
  #	
  ...	
  
	
  	
  def	
  formatted_address	
  
	
  	
  	
  	
  "%s	
  Nº	
  %s	
  %s	
  -­‐	
  CEP:	
  %s"	
  %	
  [street,	
  number,	
  city,	
  zip]	
  
	
  	
  end	
  
end
–Jamie Zawinksi
“Some people, when confronted with a problem,
think, “I know, I’ll use regular expressions.” Now
they have two problems.”
http://davidcel.is/blog/2012/09/06/stop-validating-email-addresses-with-regex/
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :email,	
  format:	
  {	
  with:	
  /A[^@]+@([^@.]+.)+[^@.]+z/	
  }	
  
end
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :email,	
  format:	
  {	
  with:	
  /A[^@]+@([^@.]+.)+[^@.]+z/	
  }	
  
end
class	
  EmailValidator	
  <	
  ActiveModel::EachValidator	
  
	
  	
  def	
  validate_each(record,	
  attribute,	
  value)	
  
	
  	
  	
  	
  unless	
  email_valid?(value)	
  
	
  	
  	
  	
  	
  	
  record.errors[attribute]	
  <<	
  (options[:message]	
  ||	
  "must	
  be	
  a	
  valid	
  email")	
  
	
  	
  	
  	
  end	
  
	
  	
  end	
  
	
  def	
  email_valid?(email)	
  
	
  	
  	
  	
  Mail::Address.new(email)	
  
	
  	
  	
  	
  true	
  
	
  	
  rescue	
  Mail::Field::ParseError	
  =>	
  e	
  
	
  	
  	
  	
  false	
  
	
  	
  end	
  	
  
end
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :email,	
  format:	
  {	
  with:	
  /A[^@]+@([^@.]+.)+[^@.]+z/	
  }	
  
end
class	
  EmailValidator	
  <	
  ActiveModel::EachValidator	
  
	
  	
  def	
  validate_each(record,	
  attribute,	
  value)	
  
	
  	
  	
  	
  unless	
  email_valid?(value)	
  
	
  	
  	
  	
  	
  	
  record.errors[attribute]	
  <<	
  (options[:message]	
  ||	
  "must	
  be	
  a	
  valid	
  email")	
  
	
  	
  	
  	
  end	
  
	
  	
  end	
  
	
  def	
  email_valid?(email)	
  
	
  	
  	
  	
  Mail::Address.new(email)	
  
	
  	
  	
  	
  true	
  
	
  	
  rescue	
  Mail::Field::ParseError	
  =>	
  e	
  
	
  	
  	
  	
  false	
  
	
  	
  end	
  	
  
end
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :email,	
  format:	
  {	
  with:	
  /A[^@]+@([^@.]+.)+[^@.]+z/	
  }	
  
end
class	
  EmailValidator	
  <	
  ActiveModel::EachValidator	
  
	
  	
  def	
  validate_each(record,	
  attribute,	
  value)	
  
	
  	
  	
  	
  unless	
  email_valid?(value)	
  
	
  	
  	
  	
  	
  	
  record.errors[attribute]	
  <<	
  (options[:message]	
  ||	
  "must	
  be	
  a	
  valid	
  email")	
  
	
  	
  	
  	
  end	
  
	
  	
  end	
  
	
  def	
  email_valid?(email)	
  
	
  	
  	
  	
  Mail::Address.new(email)	
  
	
  	
  	
  	
  true	
  
	
  	
  rescue	
  Mail::Field::ParseError	
  =>	
  e	
  
	
  	
  	
  	
  false	
  
	
  	
  end	
  	
  
end
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :email,	
  email:	
  true	
  
end
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :link,	
  format:	
  {	
  with:	
  
	
  	
  	
  	
  /(^$)|(^(http|https)://[a-­‐z0-­‐9]+([-­‐.]{1}[a-­‐z0-­‐9]+)*.[a-­‐z]{2,5}(([0-­‐9]{1,5})?/.*)?$)/ix	
  
	
  	
  }	
  
end
https://coderwall.com/p/ztig5g/validate-urls-in-rails
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :link,	
  format:	
  {	
  with:	
  
	
  	
  	
  	
  /(^$)|(^(http|https)://[a-­‐z0-­‐9]+([-­‐.]{1}[a-­‐z0-­‐9]+)*.[a-­‐z]{2,5}(([0-­‐9]{1,5})?/.*)?$)/ix	
  
	
  	
  }	
  
end
https://coderwall.com/p/ztig5g/validate-urls-in-rails
class	
  UrlValidator	
  <	
  ActiveModel::EachValidator	
  
	
  	
  def	
  validate_each(record,	
  attribute,	
  value)	
  
	
  	
  	
  	
  unless	
  url_valid?(value)	
  
	
  	
  	
  	
  	
  	
  record.errors[attribute]	
  <<	
  (options[:message]	
  ||	
  "must	
  be	
  a	
  valid	
  URL")	
  
	
  	
  	
  	
  end	
  
	
  	
  end	
  
	
  	
  #	
  a	
  URL	
  may	
  be	
  technically	
  well-­‐formed	
  but	
  may	
  	
  
	
  	
  #	
  not	
  actually	
  be	
  valid,	
  so	
  this	
  checks	
  for	
  both.	
  
	
  	
  def	
  url_valid?(url)	
  
	
  	
  	
  	
  url	
  =	
  URI.parse(url)	
  rescue	
  false	
  
	
  	
  	
  	
  url.kind_of?(URI::HTTP)	
  ||	
  url.kind_of?(URI::HTTPS)	
  
	
  	
  end	
  	
  
end
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :link,	
  format:	
  {	
  with:	
  
	
  	
  	
  	
  /(^$)|(^(http|https)://[a-­‐z0-­‐9]+([-­‐.]{1}[a-­‐z0-­‐9]+)*.[a-­‐z]{2,5}(([0-­‐9]{1,5})?/.*)?$)/ix	
  
	
  	
  }	
  
end
https://coderwall.com/p/ztig5g/validate-urls-in-rails
class	
  UrlValidator	
  <	
  ActiveModel::EachValidator	
  
	
  	
  def	
  validate_each(record,	
  attribute,	
  value)	
  
	
  	
  	
  	
  unless	
  url_valid?(value)	
  
	
  	
  	
  	
  	
  	
  record.errors[attribute]	
  <<	
  (options[:message]	
  ||	
  "must	
  be	
  a	
  valid	
  URL")	
  
	
  	
  	
  	
  end	
  
	
  	
  end	
  
	
  	
  #	
  a	
  URL	
  may	
  be	
  technically	
  well-­‐formed	
  but	
  may	
  	
  
	
  	
  #	
  not	
  actually	
  be	
  valid,	
  so	
  this	
  checks	
  for	
  both.	
  
	
  	
  def	
  url_valid?(url)	
  
	
  	
  	
  	
  url	
  =	
  URI.parse(url)	
  rescue	
  false	
  
	
  	
  	
  	
  url.kind_of?(URI::HTTP)	
  ||	
  url.kind_of?(URI::HTTPS)	
  
	
  	
  end	
  	
  
end
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :link,	
  url:	
  true	
  
end
class	
  User	
  <	
  ActiveRecord::Base	
  
	
  	
  validates	
  :link,	
  format:	
  {	
  with:	
  
	
  	
  	
  	
  /(^$)|(^(http|https)://[a-­‐z0-­‐9]+([-­‐.]{1}[a-­‐z0-­‐9]+)*.[a-­‐z]{2,5}(([0-­‐9]{1,5})?/.*)?$)/ix	
  
	
  	
  }	
  
end
https://coderwall.com/p/ztig5g/validate-urls-in-rails
class	
  UrlValidator	
  <	
  ActiveModel::EachValidator	
  
	
  	
  def	
  validate_each(record,	
  attribute,	
  value)	
  
	
  	
  	
  	
  unless	
  url_valid?(value)	
  
	
  	
  	
  	
  	
  	
  record.errors[attribute]	
  <<	
  (options[:message]	
  ||	
  "must	
  be	
  a	
  valid	
  URL")	
  
	
  	
  	
  	
  end	
  
	
  	
  end	
  
	
  	
  #	
  a	
  URL	
  may	
  be	
  technically	
  well-­‐formed	
  but	
  may	
  	
  
	
  	
  #	
  not	
  actually	
  be	
  valid,	
  so	
  this	
  checks	
  for	
  both.	
  
	
  	
  def	
  url_valid?(url)	
  
	
  	
  	
  	
  url	
  =	
  URI.parse(url)	
  rescue	
  false	
  
	
  	
  	
  	
  url.kind_of?(URI::HTTP)	
  ||	
  url.kind_of?(URI::HTTPS)	
  
	
  	
  end	
  	
  
end
def	
  query	
  
	
  	
  Vote.connection.select_values	
  <<-­‐SQL	
  
	
  	
  	
  	
  SELECT	
  voteable_id	
  
	
  	
  	
  	
  FROM	
  votes	
  
	
  	
  	
  	
  LEFT	
  OUTER	
  JOIN	
  authorships	
  ON	
  authorships.bill_id	
  =	
  voteable_id	
  
	
  	
  	
  	
  LEFT	
  OUTER	
  JOIN	
  politicians	
  ON	
  politicians.id	
  =	
  politician_id	
  
	
  	
  	
  	
  WHERE	
  voteable_type	
  =	
  'Bill'	
  
	
  	
  	
  	
  	
  	
  AND	
  person_type	
  =	
  'User'	
  
	
  	
  	
  	
  	
  	
  AND	
  votes.created_at	
  >=	
  now()	
  -­‐	
  interval	
  '90	
  days'	
  
	
  	
  	
  	
  	
  	
  #{@condition.present??	
  "AND	
  #{@condition}"	
  :	
  ""}	
  
	
  	
  	
  	
  GROUP	
  BY	
  voteable_id	
  
	
  	
  	
  	
  ORDER	
  BY	
  count(*)	
  DESC	
  LIMIT	
  6;	
  
	
  	
  SQL	
  
end
http://guides.rubyonrails.org/active_record_querying.html
def	
  query	
  
	
  	
  Vote.connection.select_values	
  <<-­‐SQL	
  
	
  	
  	
  	
  SELECT	
  voteable_id	
  
	
  	
  	
  	
  FROM	
  votes	
  
	
  	
  	
  	
  LEFT	
  OUTER	
  JOIN	
  authorships	
  ON	
  authorships.bill_id	
  =	
  voteable_id	
  
	
  	
  	
  	
  LEFT	
  OUTER	
  JOIN	
  politicians	
  ON	
  politicians.id	
  =	
  politician_id	
  
	
  	
  	
  	
  WHERE	
  voteable_type	
  =	
  'Bill'	
  
	
  	
  	
  	
  	
  	
  AND	
  person_type	
  =	
  'User'	
  
	
  	
  	
  	
  	
  	
  AND	
  votes.created_at	
  >=	
  now()	
  -­‐	
  interval	
  '90	
  days'	
  
	
  	
  	
  	
  	
  	
  #{@condition.present??	
  "AND	
  #{@condition}"	
  :	
  ""}	
  
	
  	
  	
  	
  GROUP	
  BY	
  voteable_id	
  
	
  	
  	
  	
  ORDER	
  BY	
  count(*)	
  DESC	
  LIMIT	
  6;	
  
	
  	
  SQL	
  
end
def	
  query	
  
	
  	
  query	
  =	
  Vote.select('voteable_id')	
  
	
  	
  	
  	
  joins("LEFT	
  OUTER	
  JOIN	
  authorships	
  ON	
  authorships.bill_id	
  =	
  voteable_id").	
  
	
  	
  	
  	
  joins("LEFT	
  OUTER	
  JOIN	
  politicians	
  ON	
  politicians.id	
  =	
  politician_id").	
  
	
  	
  	
  	
  where(voteable_type:	
  'Bill',	
  person_type:	
  'User').	
  
	
  	
  	
  	
  where("votes.created_at	
  >=	
  now()	
  -­‐	
  interval	
  '90	
  days'").	
  
	
  	
  	
  	
  group('voteable_id').	
  
	
  	
  	
  	
  order('count(*)	
  desc').	
  
	
  	
  	
  	
  limit(6)	
  
	
  	
  query	
  =	
  query.where(@condition)	
  if	
  @condition.present?	
  
	
  	
  query	
  
end
http://guides.rubyonrails.org/active_record_querying.html
OBRIGADO!
@akitaonrails

Más contenido relacionado

La actualidad más candente

The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of TransductionDavid Stockton
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askAndrea Giuliano
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsDavid Golden
 
Jquery In Rails
Jquery In RailsJquery In Rails
Jquery In Railsshen liu
 
Writing Sensible Code
Writing Sensible CodeWriting Sensible Code
Writing Sensible CodeAnis Ahmad
 
WordPress 3.1 at DC PHP
WordPress 3.1 at DC PHPWordPress 3.1 at DC PHP
WordPress 3.1 at DC PHPandrewnacin
 
앱스프레소를 이용한 모바일 앱 개발(2)
앱스프레소를 이용한 모바일 앱 개발(2)앱스프레소를 이용한 모바일 앱 개발(2)
앱스프레소를 이용한 모바일 앱 개발(2)mosaicnet
 
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜Takashi Kitano
 
{tidygraph}と{ggraph}によるモダンなネットワーク分析
{tidygraph}と{ggraph}によるモダンなネットワーク分析{tidygraph}と{ggraph}によるモダンなネットワーク分析
{tidygraph}と{ggraph}によるモダンなネットワーク分析Takashi Kitano
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python DevelopersCarlos Vences
 
HTML5 and CSS3 Refresher
HTML5 and CSS3 RefresherHTML5 and CSS3 Refresher
HTML5 and CSS3 RefresherIvano Malavolta
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 
WordCamp Denver 2012 - Custom Meta Boxes
WordCamp Denver 2012 - Custom Meta BoxesWordCamp Denver 2012 - Custom Meta Boxes
WordCamp Denver 2012 - Custom Meta BoxesJeremy Green
 

La actualidad más candente (20)

The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of Transduction
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
JQuery Flot
JQuery FlotJQuery Flot
JQuery Flot
 
JQuery Basics
JQuery BasicsJQuery Basics
JQuery Basics
 
Jquery In Rails
Jquery In RailsJquery In Rails
Jquery In Rails
 
The jQuery Divide
The jQuery DivideThe jQuery Divide
The jQuery Divide
 
Writing Sensible Code
Writing Sensible CodeWriting Sensible Code
Writing Sensible Code
 
WordPress 3.1 at DC PHP
WordPress 3.1 at DC PHPWordPress 3.1 at DC PHP
WordPress 3.1 at DC PHP
 
[ HackFest.pl 2012] Testing - what for and how
[ HackFest.pl 2012] Testing - what for and how[ HackFest.pl 2012] Testing - what for and how
[ HackFest.pl 2012] Testing - what for and how
 
Solid in practice
Solid in practiceSolid in practice
Solid in practice
 
앱스프레소를 이용한 모바일 앱 개발(2)
앱스프레소를 이용한 모바일 앱 개발(2)앱스프레소를 이용한 모바일 앱 개발(2)
앱스프레소를 이용한 모바일 앱 개발(2)
 
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
 
{tidygraph}と{ggraph}によるモダンなネットワーク分析
{tidygraph}と{ggraph}によるモダンなネットワーク分析{tidygraph}と{ggraph}によるモダンなネットワーク分析
{tidygraph}と{ggraph}によるモダンなネットワーク分析
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python Developers
 
HTML5 and CSS3 Refresher
HTML5 and CSS3 RefresherHTML5 and CSS3 Refresher
HTML5 and CSS3 Refresher
 
Presentation1
Presentation1Presentation1
Presentation1
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 
5th Sem SS lab progs
5th Sem SS lab progs5th Sem SS lab progs
5th Sem SS lab progs
 
WordCamp Denver 2012 - Custom Meta Boxes
WordCamp Denver 2012 - Custom Meta BoxesWordCamp Denver 2012 - Custom Meta Boxes
WordCamp Denver 2012 - Custom Meta Boxes
 

Similar a WTF Oriented Programming Techniques

Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB jhchabran
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackVic Metcalfe
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding HorrorsMark Baker
 
Using R for Building a Simple and Effective Dashboard
Using R for Building a Simple and Effective DashboardUsing R for Building a Simple and Effective Dashboard
Using R for Building a Simple and Effective DashboardAndrea Gigli
 
次世代版 PowerCMS 開発プロジェクトのご紹介
次世代版 PowerCMS 開発プロジェクトのご紹介次世代版 PowerCMS 開発プロジェクトのご紹介
次世代版 PowerCMS 開発プロジェクトのご紹介純生 野田
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form componentSamuel ROZE
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From IusethisMarcus Ramberg
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and ProfitOlaf Alders
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
Youth Tobacco Survey Analysis
Youth Tobacco Survey AnalysisYouth Tobacco Survey Analysis
Youth Tobacco Survey AnalysisRoshik Ganesan
 
Modern JavaScript Engine Performance
Modern JavaScript Engine PerformanceModern JavaScript Engine Performance
Modern JavaScript Engine PerformanceCatalin Dumitru
 
Historical Finance Data
Historical Finance DataHistorical Finance Data
Historical Finance DataJEE HYUN PARK
 
Wx::Perl::Smart
Wx::Perl::SmartWx::Perl::Smart
Wx::Perl::Smartlichtkind
 

Similar a WTF Oriented Programming Techniques (20)

Zero to SOLID
Zero to SOLIDZero to SOLID
Zero to SOLID
 
Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB Introduction à CoffeeScript pour ParisRB
Introduction à CoffeeScript pour ParisRB
 
php Mailer
php Mailerphp Mailer
php Mailer
 
Php functions
Php functionsPhp functions
Php functions
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
 
Php
PhpPhp
Php
 
Coding Horrors
Coding HorrorsCoding Horrors
Coding Horrors
 
Using R for Building a Simple and Effective Dashboard
Using R for Building a Simple and Effective DashboardUsing R for Building a Simple and Effective Dashboard
Using R for Building a Simple and Effective Dashboard
 
次世代版 PowerCMS 開発プロジェクトのご紹介
次世代版 PowerCMS 開発プロジェクトのご紹介次世代版 PowerCMS 開発プロジェクトのご紹介
次世代版 PowerCMS 開発プロジェクトのご紹介
 
PowerCMS X
PowerCMS XPowerCMS X
PowerCMS X
 
Symfony CoP: Form component
Symfony CoP: Form componentSymfony CoP: Form component
Symfony CoP: Form component
 
Bag Of Tricks From Iusethis
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 
Youth Tobacco Survey Analysis
Youth Tobacco Survey AnalysisYouth Tobacco Survey Analysis
Youth Tobacco Survey Analysis
 
Modern JavaScript Engine Performance
Modern JavaScript Engine PerformanceModern JavaScript Engine Performance
Modern JavaScript Engine Performance
 
Theme verdadeiro
Theme verdadeiroTheme verdadeiro
Theme verdadeiro
 
C questions
C questionsC questions
C questions
 
Historical Finance Data
Historical Finance DataHistorical Finance Data
Historical Finance Data
 
Wx::Perl::Smart
Wx::Perl::SmartWx::Perl::Smart
Wx::Perl::Smart
 

Más de Fabio Akita

Devconf 2019 - São Carlos
Devconf 2019 - São CarlosDevconf 2019 - São Carlos
Devconf 2019 - São CarlosFabio Akita
 
Meetup Nerdzão - English Talk about Languages
Meetup Nerdzão  - English Talk about LanguagesMeetup Nerdzão  - English Talk about Languages
Meetup Nerdzão - English Talk about LanguagesFabio Akita
 
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018Fabio Akita
 
Desmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SPDesmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SPFabio Akita
 
Desmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter GoianiaDesmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter GoianiaFabio Akita
 
Blockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7MastersBlockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7MastersFabio Akita
 
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG CampinasFabio Akita
 
Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017Fabio Akita
 
30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to Ruby30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to RubyFabio Akita
 
Uma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TIUma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TIFabio Akita
 
THE CONF - Opening Keynote
THE CONF - Opening KeynoteTHE CONF - Opening Keynote
THE CONF - Opening KeynoteFabio Akita
 
A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017Fabio Akita
 
Desmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - APDesmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - APFabio Akita
 
A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017Fabio Akita
 
A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017Fabio Akita
 
A Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech DayA Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech DayFabio Akita
 
A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016Fabio Akita
 
Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016Fabio Akita
 
Conexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização PrematuraConexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização PrematuraFabio Akita
 
The Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All EvilThe Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All EvilFabio Akita
 

Más de Fabio Akita (20)

Devconf 2019 - São Carlos
Devconf 2019 - São CarlosDevconf 2019 - São Carlos
Devconf 2019 - São Carlos
 
Meetup Nerdzão - English Talk about Languages
Meetup Nerdzão  - English Talk about LanguagesMeetup Nerdzão  - English Talk about Languages
Meetup Nerdzão - English Talk about Languages
 
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
Desmistificando Blockchains p/ Developers - Criciuma Dev Conf 2018
 
Desmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SPDesmistificando Blockchains - 20o Encontro Locaweb SP
Desmistificando Blockchains - 20o Encontro Locaweb SP
 
Desmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter GoianiaDesmistificando Blockchains - Insiter Goiania
Desmistificando Blockchains - Insiter Goiania
 
Blockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7MastersBlockchain em 7 minutos - 7Masters
Blockchain em 7 minutos - 7Masters
 
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
Elixir  -Tolerância a Falhas para Adultos - GDG CampinasElixir  -Tolerância a Falhas para Adultos - GDG Campinas
Elixir -Tolerância a Falhas para Adultos - GDG Campinas
 
Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017Desmistificando Mitos de Tech Startups - Intercon 2017
Desmistificando Mitos de Tech Startups - Intercon 2017
 
30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to Ruby30 Days to Elixir and Crystal and Back to Ruby
30 Days to Elixir and Crystal and Back to Ruby
 
Uma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TIUma Discussão sobre a Carreira de TI
Uma Discussão sobre a Carreira de TI
 
THE CONF - Opening Keynote
THE CONF - Opening KeynoteTHE CONF - Opening Keynote
THE CONF - Opening Keynote
 
A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017A Journey through New Languages - Rancho Dev 2017
A Journey through New Languages - Rancho Dev 2017
 
Desmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - APDesmistificando Mitos de Startups - Sebrae - AP
Desmistificando Mitos de Startups - Sebrae - AP
 
A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017A Journey through New Languages - Guru Sorocaba 2017
A Journey through New Languages - Guru Sorocaba 2017
 
A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017A Journey through New Languages - Insiter 2017
A Journey through New Languages - Insiter 2017
 
A Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech DayA Journey through New Languages - Locaweb Tech Day
A Journey through New Languages - Locaweb Tech Day
 
A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016A Journey through new Languages - Intercon 2016
A Journey through new Languages - Intercon 2016
 
Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016Premature Optimization 2.0 - Intercon 2016
Premature Optimization 2.0 - Intercon 2016
 
Conexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização PrematuraConexão Kinghost - Otimização Prematura
Conexão Kinghost - Otimização Prematura
 
The Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All EvilThe Open Commerce Conference - Premature Optimisation: The Root of All Evil
The Open Commerce Conference - Premature Optimisation: The Root of All Evil
 

Último

Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 

Último (20)

Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 

WTF Oriented Programming Techniques

  • 2.
  • 3.
  • 4.
  • 5.
  • 6. $('a').click(function(){          window.location  =  $(a).attr('href');   })
  • 7. project_id  =  @user.project  ==  nil  ?  nil  :  @user.project.id
  • 8. project_id  =  @user.project  ==  nil  ?  nil  :  @user.project.id project_id  =  @user.try(:project).try(:id)
  • 9. @politician  =  Politician.where(name:  "Terminator").first   puts  @politician.try(:studio).try(:name)
  • 10. @politician  =  Politician.where(name:  "Terminator").first   puts  @politician.try(:studio).try(:name) LAW OF DEMETER
  • 11. @politician  =  Politician.where(name:  "Terminator").first   puts  @politician.try(:studio).try(:name) LAW OF DEMETER
  • 12. class  Politician      delegate  :name,  to:  :studio,          prefix:  true,  allow_nil:  true      #  ...   end   @politician.studio.name
  • 13. class  Politician      delegate  :name,  to:  :studio,          prefix:  true,  allow_nil:  true      #  ...   end   @politician.studio.name@politician.studio_name
  • 14. class  Politician      delegate  :name,  to:  :studio,          prefix:  true,  allow_nil:  true      #  ...   end   @politician.studio.name@politician.studio_name
  • 15.
  • 16. array  =  []   list.each  do  |state|      array  <<  [state.name,  state.acronym]   end   array
  • 17. array  =  []   list.each  do  |state|      array  <<  [state.name,  state.acronym]   end   array for  state  in  list
  • 18. array  =  []   list.each  do  |state|      array  <<  [state.name,  state.acronym]   end   array list.map  {  |state|  [state.name,  state.acronym]  } for  state  in  list
  • 19. array  =  []   list.each  do  |state|      if  state.name  =~  /^S/          array  <<  [state.name,  state.acronym]      end   end   array
  • 20. array  =  []   list.each  do  |state|      if  state.name  =~  /^S/          array  <<  [state.name,  state.acronym]      end   end   array list.      select  {  |state|  state.name  =~  /^S/  }.      map  {  |state|  [state.name,  state.acronym]  }
  • 21. def  formatdate(d)          months  =  Hash.new          months["Jan"]  =  "janeiro"          months["Feb"]  =  "fevereiro"          #  ...          months["Dec"]  =  "dezembro"              weeks  =  Hash.new          weeks["Sun"]  =  "Domingo"          #  ...          weeks["Fri"]  =  "Sexta"          weeks["Sat"]  =  "Sábado"                    return  weeks[d.strftime("%a")]+",  "+d.strftime("%d")+"  de  "+months[d.strftime("%b")]   end
  • 22. def  formatdate(d)          months  =  Hash.new          months["Jan"]  =  "janeiro"          months["Feb"]  =  "fevereiro"          #  ...          months["Dec"]  =  "dezembro"              weeks  =  Hash.new          weeks["Sun"]  =  "Domingo"          #  ...          weeks["Fri"]  =  "Sexta"          weeks["Sat"]  =  "Sábado"                    return  weeks[d.strftime("%a")]+",  "+d.strftime("%d")+"  de  "+months[d.strftime("%b")]   end #  config/locales/pt-­‐BR.yml   pt-­‐BR:      time:          formats:              short_wday:  "%a,  %d  de  %B”   d.to_s(:short_wday)
  • 23. .row      .wrap-­‐select          select.payment-­‐select              -­‐  if  @payment_type  ==  'pagamento'                  option.icons-­‐select.card-­‐credit[value="pagamento"  data-­‐foo="card-­‐credit"  selected]  Pagamento              -­‐  else                  option.icons-­‐select.card-­‐credit  value="pagamento"  data-­‐foo="card-­‐credit"  Pagamento              -­‐  if  @payment_type.include?  'cartao'                  option.icons-­‐select.card-­‐credit[value="cartao"  data-­‐foo="card-­‐credit"  selected]  Cartão              -­‐  else                  option.icons-­‐select.card-­‐credit  value="cartao"  data-­‐foo="card-­‐credit"  Cartão              -­‐  if  @payment_type  ==  'dinheiro'                  option.icons-­‐select.cash[value="dinheiro"  data-­‐foo="cash"  selected]  Dinheiro              -­‐  else                  option.icons-­‐select.cash  value="dinheiro"  data-­‐foo="cash"  Dinheiro              -­‐  if  @payment_type  ==  'boleto'                  option.icons-­‐select.banking-­‐billet[value="boleto"  data-­‐foo="banking-­‐billet"  selected]  Boleto              -­‐  else                  option.icons-­‐select.banking-­‐billet  value="boleto"  data-­‐foo="banking-­‐billet"  Boleto
  • 24. .row      .wrap-­‐select          select.payment-­‐select              -­‐  if  @payment_type  ==  'pagamento'                  option.icons-­‐select.card-­‐credit[value="pagamento"  data-­‐foo="card-­‐credit"  selected]  Pagamento              -­‐  else                  option.icons-­‐select.card-­‐credit  value="pagamento"  data-­‐foo="card-­‐credit"  Pagamento              -­‐  if  @payment_type.include?  'cartao'                  option.icons-­‐select.card-­‐credit[value="cartao"  data-­‐foo="card-­‐credit"  selected]  Cartão              -­‐  else                  option.icons-­‐select.card-­‐credit  value="cartao"  data-­‐foo="card-­‐credit"  Cartão              -­‐  if  @payment_type  ==  'dinheiro'                  option.icons-­‐select.cash[value="dinheiro"  data-­‐foo="cash"  selected]  Dinheiro              -­‐  else                  option.icons-­‐select.cash  value="dinheiro"  data-­‐foo="cash"  Dinheiro              -­‐  if  @payment_type  ==  'boleto'                  option.icons-­‐select.banking-­‐billet[value="boleto"  data-­‐foo="banking-­‐billet"  selected]  Boleto              -­‐  else                  option.icons-­‐select.banking-­‐billet  value="boleto"  data-­‐foo="banking-­‐billet"  Boleto .row      .wrap-­‐select          select.payment-­‐select              -­‐  pc  =  %w(card-­‐credit  card-­‐credit  cash  banking-­‐billet)              -­‐  %w(pagamento  cartao  dinheiro  boleto).each_with_index  do  |i,  ptype|                  option.icons-­‐select[class=pc[i]  value=ptype  data-­‐foo=pc[i]  selected=(@payment_type==ptype)]  I18n.t(ptype)
  • 25. <?php  if  (LANGUAGE  ==  'en')  {  ?>  <body  class="en">  <?php  }  ?>   <?php  if  (LANGUAGE  ==  'pt')  {  ?>  <body  class="pt">  <?php  }  ?>   <?php  if  (LANGUAGE  ==  'mx')  {  ?>  <body  class="mx">  <?php  }  ?>   <?php  if  (LANGUAGE  ==  'kp')  {  ?>  <body  class="kp">  <?php  }  ?>
  • 26. <?php  if  (LANGUAGE  ==  'en')  {  ?>  <body  class="en">  <?php  }  ?>   <?php  if  (LANGUAGE  ==  'pt')  {  ?>  <body  class="pt">  <?php  }  ?>   <?php  if  (LANGUAGE  ==  'mx')  {  ?>  <body  class="mx">  <?php  }  ?>   <?php  if  (LANGUAGE  ==  'kp')  {  ?>  <body  class="kp">  <?php  }  ?> <body  class="<?php  LANGUAGE  ?>">
  • 27. address  =  ((!client.street.to_s.nil?)?  client.street.to_s  :  "")  +     ((!client.number.to_s.nil?)?  "  Nº  "  +  client.number.to_s  :  "")  +  "  "  +     ((!client.city.to_s.nil?)?  client.city.to_s  :  "")  +     ((!client.zip.to_s.nil?)?  "  -­‐  CEP:  "  +  client.zip.to_s  :  "")
  • 28. address  =  ((!client.street.to_s.nil?)?  client.street.to_s  :  "")  +     ((!client.number.to_s.nil?)?  "  Nº  "  +  client.number.to_s  :  "")  +  "  "  +     ((!client.city.to_s.nil?)?  client.city.to_s  :  "")  +     ((!client.zip.to_s.nil?)?  "  -­‐  CEP:  "  +  client.zip.to_s  :  "") address  =  "#{client.street}  Nº  #{client.number}  #{client.city}  -­‐  CEP:  #{client.zip}"
  • 29. address  =  ((!client.street.to_s.nil?)?  client.street.to_s  :  "")  +     ((!client.number.to_s.nil?)?  "  Nº  "  +  client.number.to_s  :  "")  +  "  "  +     ((!client.city.to_s.nil?)?  client.city.to_s  :  "")  +     ((!client.zip.to_s.nil?)?  "  -­‐  CEP:  "  +  client.zip.to_s  :  "") address  =  "#{client.street}  Nº  #{client.number}  #{client.city}  -­‐  CEP:  #{client.zip}" address  =  "%s  Nº  %s  %s  -­‐  CEP:  %s"  %  [client.street,  client.number,  client.city,  client.zip]
  • 30. address  =  ((!client.street.to_s.nil?)?  client.street.to_s  :  "")  +     ((!client.number.to_s.nil?)?  "  Nº  "  +  client.number.to_s  :  "")  +  "  "  +     ((!client.city.to_s.nil?)?  client.city.to_s  :  "")  +     ((!client.zip.to_s.nil?)?  "  -­‐  CEP:  "  +  client.zip.to_s  :  "") address  =  "#{client.street}  Nº  #{client.number}  #{client.city}  -­‐  CEP:  #{client.zip}" address  =  "%s  Nº  %s  %s  -­‐  CEP:  %s"  %  [client.street,  client.number,  client.city,  client.zip] class  ClientDecorator      #  ...      def  formatted_address          "%s  Nº  %s  %s  -­‐  CEP:  %s"  %  [street,  number,  city,  zip]      end   end
  • 31. –Jamie Zawinksi “Some people, when confronted with a problem, think, “I know, I’ll use regular expressions.” Now they have two problems.” http://davidcel.is/blog/2012/09/06/stop-validating-email-addresses-with-regex/
  • 32. class  User  <  ActiveRecord::Base      validates  :email,  format:  {  with:  /A[^@]+@([^@.]+.)+[^@.]+z/  }   end
  • 33. class  User  <  ActiveRecord::Base      validates  :email,  format:  {  with:  /A[^@]+@([^@.]+.)+[^@.]+z/  }   end class  EmailValidator  <  ActiveModel::EachValidator      def  validate_each(record,  attribute,  value)          unless  email_valid?(value)              record.errors[attribute]  <<  (options[:message]  ||  "must  be  a  valid  email")          end      end    def  email_valid?(email)          Mail::Address.new(email)          true      rescue  Mail::Field::ParseError  =>  e          false      end     end
  • 34. class  User  <  ActiveRecord::Base      validates  :email,  format:  {  with:  /A[^@]+@([^@.]+.)+[^@.]+z/  }   end class  EmailValidator  <  ActiveModel::EachValidator      def  validate_each(record,  attribute,  value)          unless  email_valid?(value)              record.errors[attribute]  <<  (options[:message]  ||  "must  be  a  valid  email")          end      end    def  email_valid?(email)          Mail::Address.new(email)          true      rescue  Mail::Field::ParseError  =>  e          false      end     end
  • 35. class  User  <  ActiveRecord::Base      validates  :email,  format:  {  with:  /A[^@]+@([^@.]+.)+[^@.]+z/  }   end class  EmailValidator  <  ActiveModel::EachValidator      def  validate_each(record,  attribute,  value)          unless  email_valid?(value)              record.errors[attribute]  <<  (options[:message]  ||  "must  be  a  valid  email")          end      end    def  email_valid?(email)          Mail::Address.new(email)          true      rescue  Mail::Field::ParseError  =>  e          false      end     end class  User  <  ActiveRecord::Base      validates  :email,  email:  true   end
  • 36.
  • 37. class  User  <  ActiveRecord::Base      validates  :link,  format:  {  with:          /(^$)|(^(http|https)://[a-­‐z0-­‐9]+([-­‐.]{1}[a-­‐z0-­‐9]+)*.[a-­‐z]{2,5}(([0-­‐9]{1,5})?/.*)?$)/ix      }   end https://coderwall.com/p/ztig5g/validate-urls-in-rails
  • 38. class  User  <  ActiveRecord::Base      validates  :link,  format:  {  with:          /(^$)|(^(http|https)://[a-­‐z0-­‐9]+([-­‐.]{1}[a-­‐z0-­‐9]+)*.[a-­‐z]{2,5}(([0-­‐9]{1,5})?/.*)?$)/ix      }   end https://coderwall.com/p/ztig5g/validate-urls-in-rails class  UrlValidator  <  ActiveModel::EachValidator      def  validate_each(record,  attribute,  value)          unless  url_valid?(value)              record.errors[attribute]  <<  (options[:message]  ||  "must  be  a  valid  URL")          end      end      #  a  URL  may  be  technically  well-­‐formed  but  may        #  not  actually  be  valid,  so  this  checks  for  both.      def  url_valid?(url)          url  =  URI.parse(url)  rescue  false          url.kind_of?(URI::HTTP)  ||  url.kind_of?(URI::HTTPS)      end     end
  • 39. class  User  <  ActiveRecord::Base      validates  :link,  format:  {  with:          /(^$)|(^(http|https)://[a-­‐z0-­‐9]+([-­‐.]{1}[a-­‐z0-­‐9]+)*.[a-­‐z]{2,5}(([0-­‐9]{1,5})?/.*)?$)/ix      }   end https://coderwall.com/p/ztig5g/validate-urls-in-rails class  UrlValidator  <  ActiveModel::EachValidator      def  validate_each(record,  attribute,  value)          unless  url_valid?(value)              record.errors[attribute]  <<  (options[:message]  ||  "must  be  a  valid  URL")          end      end      #  a  URL  may  be  technically  well-­‐formed  but  may        #  not  actually  be  valid,  so  this  checks  for  both.      def  url_valid?(url)          url  =  URI.parse(url)  rescue  false          url.kind_of?(URI::HTTP)  ||  url.kind_of?(URI::HTTPS)      end     end
  • 40. class  User  <  ActiveRecord::Base      validates  :link,  url:  true   end class  User  <  ActiveRecord::Base      validates  :link,  format:  {  with:          /(^$)|(^(http|https)://[a-­‐z0-­‐9]+([-­‐.]{1}[a-­‐z0-­‐9]+)*.[a-­‐z]{2,5}(([0-­‐9]{1,5})?/.*)?$)/ix      }   end https://coderwall.com/p/ztig5g/validate-urls-in-rails class  UrlValidator  <  ActiveModel::EachValidator      def  validate_each(record,  attribute,  value)          unless  url_valid?(value)              record.errors[attribute]  <<  (options[:message]  ||  "must  be  a  valid  URL")          end      end      #  a  URL  may  be  technically  well-­‐formed  but  may        #  not  actually  be  valid,  so  this  checks  for  both.      def  url_valid?(url)          url  =  URI.parse(url)  rescue  false          url.kind_of?(URI::HTTP)  ||  url.kind_of?(URI::HTTPS)      end     end
  • 41. def  query      Vote.connection.select_values  <<-­‐SQL          SELECT  voteable_id          FROM  votes          LEFT  OUTER  JOIN  authorships  ON  authorships.bill_id  =  voteable_id          LEFT  OUTER  JOIN  politicians  ON  politicians.id  =  politician_id          WHERE  voteable_type  =  'Bill'              AND  person_type  =  'User'              AND  votes.created_at  >=  now()  -­‐  interval  '90  days'              #{@condition.present??  "AND  #{@condition}"  :  ""}          GROUP  BY  voteable_id          ORDER  BY  count(*)  DESC  LIMIT  6;      SQL   end http://guides.rubyonrails.org/active_record_querying.html
  • 42. def  query      Vote.connection.select_values  <<-­‐SQL          SELECT  voteable_id          FROM  votes          LEFT  OUTER  JOIN  authorships  ON  authorships.bill_id  =  voteable_id          LEFT  OUTER  JOIN  politicians  ON  politicians.id  =  politician_id          WHERE  voteable_type  =  'Bill'              AND  person_type  =  'User'              AND  votes.created_at  >=  now()  -­‐  interval  '90  days'              #{@condition.present??  "AND  #{@condition}"  :  ""}          GROUP  BY  voteable_id          ORDER  BY  count(*)  DESC  LIMIT  6;      SQL   end def  query      query  =  Vote.select('voteable_id')          joins("LEFT  OUTER  JOIN  authorships  ON  authorships.bill_id  =  voteable_id").          joins("LEFT  OUTER  JOIN  politicians  ON  politicians.id  =  politician_id").          where(voteable_type:  'Bill',  person_type:  'User').          where("votes.created_at  >=  now()  -­‐  interval  '90  days'").          group('voteable_id').          order('count(*)  desc').          limit(6)      query  =  query.where(@condition)  if  @condition.present?      query   end http://guides.rubyonrails.org/active_record_querying.html
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.