0

In episode 389 of Railscasts, he creates a method called scope_schema which is both a method being used throughout the episode but also being passed as a block with do

Can any method be done as such? What does the (*paths) stand for? And how can I just create a method that can be a block? I looked at the link_to source code and noticed at the end &block which could make send given you can do

<%= link_to ....%>

or

<%= link_to ... do %>

<%end%>

Or am I incorrect?

Episode code:

after_create :create_schema

def create_schema
  connection.execute("create schema tenant#{id}")
  scope_schema do
    load Rails.root.join("db/schema.rb")
    connection.execute("drop table #{self.class.table_name}")
  end
end

def scope_schema(*paths)
  original_search_path = connection.schema_search_path
  connection.schema_search_path = ["tenant#{id}", *paths].join(",")
  yield
ensure
  connection.schema_search_path = original_search_path
end
Mohamed El Mahallawy
  • 13,024
  • 13
  • 52
  • 84

2 Answers2

1

Any method can be called with a block if you define it as such. The link_to code is a good example.

As for *paths, this is the splat operator, which basically means any number of arguments can be given to the method and will be read as the same argument - in this case paths - as an array.

dax
  • 10,779
  • 8
  • 51
  • 86
  • So how come in the case of `scope_schema` doesn't have a `&block` yet used with a `do` or is that due to the splat operator? – Mohamed El Mahallawy Jul 06 '14 at 18:26
  • 1
    the `yield` in the `scope_schema` method is yielding to a block - I'm sorry, I didn't understand that as being part of the question. [This answer](http://stackoverflow.com/a/3066939/2128691) covers `yield` very well. – dax Jul 06 '14 at 18:29
1

Can any method be done as such?

Yes, just make a block available in the arguments list of your method:

def method(arg1, &block)
  # do something with arg1
  # call the block with or without arguments if a block is given:
  block.call() if block_given?
end

or

def method(arg1)
  # do somehting
  yield
end

Yield can receive arguments to.

*What does the (paths) stand for?

'*' is the splat operator, giving you access to has many arguments as you want. (same as in python)

And how can I just create a method that can be a block?

A method can receive a block, or be called in a block, but cannot be a block. You can create a 'method' inside a proc, though.

a = ->(){ puts 'lalala' }

a.call
Afonso Tsukamoto
  • 1,184
  • 1
  • 12
  • 21