Slide 1

Slide 1 text

Ruby on Your Rails Akira Matsuda @ RubyKaigi 2013

Slide 2

Slide 2 text

"go west"

Slide 3

Slide 3 text

Japan.map ,ZPUP .BU[F 5PLZP

Slide 4

Slide 4 text

Tokyo.map "LJIBCBSB (JO[B

Slide 5

Slide 5 text

Tokyo.map "TBLVTB

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

The next Asakusa.rb meetup (drinkup) http://asakusarb.doorkeeper.jp/ events/4149

Slide 8

Slide 8 text

whoami Twitter: @a_matsuda GitHub: amatsuda

Slide 9

Slide 9 text

Announcement! GitHub Drinkup this evening!! https://github.com/blog/1515- tokyo-drinkup

Slide 10

Slide 10 text

amatsuda Ruby on Rails Ruby Haml Kaminari ...

Slide 11

Slide 11 text

How to "go west" on Rails

Slide 12

Slide 12 text

How can we write WHERE + NOT, WHERE + LIKE queries?

Slide 13

Slide 13 text

User.where(name: 'Matz') #=> SELECT * FROM users WHERE name = 'Matz' User.where('name != ?', 'Matz') #=> SELECT * FROM users WHERE name != 'Matz' SELECT * FROM users WHERE name != 'Matz'

Slide 14

Slide 14 text

SELECT * FROM users WHERE name != 'Matz' We should be able to do this with Hashes We were apparently missing this feature But it wasn't implemented because a good feature needs Proper use case Good API Good implementation

Slide 15

Slide 15 text

WHERE name != 'Matz' was not in AR3 not because it was not possible to implement In fact, it could be done using Arel Objects

Slide 16

Slide 16 text

where(Arel node) User.where( User.arel_table[:name].not_eq('Matz') ) #=> "SELECT `users`.* FROM `users` WHERE (`users`.`first_name` != 'Matz')"

Slide 17

Slide 17 text

WHERE name != 'Matz' was not in AR3 because We just couldn't nd a good API Syntax matters (ʮ໊લॏཁʯ)

Slide 18

Slide 18 text

Re nements... # where + block User.where { :name != 'Matz' }

Slide 19

Slide 19 text

amatsuda/everywhere A Rails plugin that enables `WHERE + NOT`, `WHERE + LIKE` and `WHERE + NOT LIKE` queries Users can switch syntax via con guration

Slide 20

Slide 20 text

everywhere # :not in Hash value User.where(name: {not: 'Matz'}) # :not in Hash key User.where(not: {name: 'Matz'}) # :not + Hash User.where(:not, name: 'foo') # special method User.where_not(name: 'foo')

Slide 21

Slide 21 text

@tenderlove & @jonleighton I don't like the idea of adding "special" hash keys me neither in fact, since I added hstore support, that technique won't work on PG

Slide 22

Slide 22 text

@bitsweat Perhaps a Model.where with no args should be chainable: Model.where.not eld: nil or Model.where.like name: 'John%'

Slide 23

Slide 23 text

Committed where.not where.like where.not_like

Slide 24

Slide 24 text

@dhh says Akira Matsuda, where.not is a beaut ul DSL solution. Props! Love when a hard problem like that turns out to have a simple DSL solution we just didn't see.

Slide 25

Slide 25 text

@dhh says imo, I think already like/not_like are going too far like/not_like are very rare cases and they just open the door to the monstrocities of gte they're also weird because you need % so it's this bastard version of half sql in the statement, half sql in the parameter Any counter arguments?

Slide 26

Slide 26 text

Then partially reverted where.not where.like where.not_like

Slide 27

Slide 27 text

Lessons learned Publish your idea as a gem so that others can investigate and give a try Jeremy is awesome. He is always right DHH is awesomer (͓͏͞·ʔ) #ବᔬམΫϥϒ AR4 now has where.not feature

Slide 28

Slide 28 text

Why our controller actions don't look like Ruby code?

Slide 29

Slide 29 text

"Merbish" controllers

Slide 30

Slide 30 text

Why aren't our actions like this? class UsersController < ApplicationController def show(id) @user = User.find(id) end end

Slide 31

Slide 31 text

"params" class UsersController < ApplicationController def show @user = User.find(params[:id]) end end

Slide 32

Slide 32 text

How our controllers work $params = {greeting: 'Hello, world!'} def foo puts $params[:greeting] end foo

Slide 33

Slide 33 text

asakusarb/action_args

Slide 34

Slide 34 text

More examples class UsersController < ApplicationController def show(id) @user = User.find(id) end def create(user) @user = User.new(user) if @user.save ... end end def update(id, user) @user = User.find(id) if @user.update_attributes(user) ... end end end end

Slide 35

Slide 35 text

@dhh says I was initially excited about it Problems with the action_args approach is that it doesn't deal with the preload pattern very gracefully You're passing in a parameter that just says "user", but it's not a user object, like the one assigned to @user, it's a set of parameters for the user. params[:user] is much more clear about what this variable actually contains

Slide 36

Slide 36 text

@dhh's conclusion I don't think it's going to work as a good t for core

Slide 37

Slide 37 text

Helpers are ugly, and my models are too fat

Slide 38

Slide 38 text

Use decorators

Slide 39

Slide 39 text

amatsuda/ active_decorator

Slide 40

Slide 40 text

I heard that our browsers can also do some form validations. Why not on my Rails app?

Slide 41

Slide 41 text

let your validations DRY

Slide 42

Slide 42 text

amatsuda/ html5_validators

Slide 43

Slide 43 text

Sexy validations? Seriously? Are they?

Slide 44

Slide 44 text

Good ol' validations class Person # validations start from here validates_presence_of :name, :age validates_length_of :name, maximum: 255 validates_numericality_of :age, greater_than: 0 # validations end ... end

Slide 45

Slide 45 text

"sexy validations" validates :name, presence: true

Slide 46

Slide 46 text

IMO It would be sexier if DRYer grouped no "{something: true} thing

Slide 47

Slide 47 text

validates + block - def validates(*attributes) + def validates(*attributes, &block)

Slide 48

Slide 48 text

validates + block class Person validates do presence_of :name, :age length_of :name, maximum: 255 numericality_of :age, greater_than: 0 end ... end

Slide 49

Slide 49 text

validates + block class Person validates :name do presence length maximum: 255 end validates :age do presence numericality greater_than: 0 end ... end

Slide 50

Slide 50 text

I can bake it into a gem, probably?

Slide 51

Slide 51 text

Conclusion Stay on the Edge Be careful and critical Try to solve YOUR problems Send your PRs!