Hack hack hack...

An open journal-- some of it written for you, but most of it is for me.

Polymorphic Brain Hurt

Polymorphic association from parent to child

So this succinctly summed up my issue.

Deprecated conditions in rails 4

Deprecation warning when using has_many :through :uniq in Rails 4

Then once I did get it working with:

Conditions Refactor
1
2
3
4
5
6
7
8
9
10
11
12
13
# lesson model
  has_many :readmes, :through => :lesson_contents, :source => :readme,
    :conditions => "lesson_contents.content_type = 'Readme'"

  has_many :labs, :through => :lesson_contents, :source => :lab,
    :conditions => "lesson_contents.content_type = 'Lab'"

# stabby lambda
  has_many :readmes, -> { where("content_type = 'Readme'") },
    :through => :lesson_contents, :source => :readme

  has_many :labs, -> { where("content_type = 'Lab'") }, :through =>
    :lesson_contents, :source => :lab

Hat Tip

Polymorphic Migration

Creating a [polymorphic migration](http://stackoverflow.com/a/5534614/1496757)
1
2
3
4
5
6
7
class AddImageableToProducts < ActiveRecord::Migration
  def up
    change_table :products do |t|
      t.references :imageable, :polymorphic => true
    end
  end
end

VIM Shortcuts

File Search

  • cntl + p => file search

Nerd Tree

  • go => preview pane

Run the specs

  • \r runs the closest spec
  • \R runs the whole spec suite

cmd + shift + d

  • control + n

vimium for life

  • \\f + character you are looking for
  • \\w + word
  • \\e goes to end of words
  • you get it

Go to line

  • line number + G

Tab in or out

  • >> & <<

Intro to Docker

Docker API

Relevant Docker Images

Pups

  • pups is a small library that allows you to automate the process of creating Unix images

Deployments

Discourse on docker

haproxy

Testing

Intro video

Commands

1
2
3
4
5
6
7
8
9
10
docker run -p 3000:3000 -t -i dockerregistry.flatironschool.com/ironboard /bin/bash
source /etc/profile.d/rvm.sh 
rvm reload
vi ironboard/config/database.yml
cd ironboard/
service postgresql start
rake db:migrate

docker build -t dockerregistry.flatironschool.com/ironboard .
docker run -d -p 3000:3000 dockerregistry.flatironschool.com/ironboard

Notes from Docker: The Revolution Will Be Containerized

  • Containers are just other Linux processes on the host not virtualized calls
  • The only performance decrease you see is Linux asking whether it is allowed to access this file - share a kernel with the host
  • Not nested virtualization

    • this would be slow
    • no device emulation, which makes it faster
  • Can be used as a light weight vm but that’s not the only way

  • Chroot on steroids?

    • (From Wikipedia) A chroot on Unix operating systems is an operation that changes the apparent root directory for the current running process and its children.

    • A chroot environment can be used to create and host a separate virtualized copy of the software system. This can be useful for:

      • Testing and development

        • A test environment can be set up in the chroot for software that would otherwise be too risky to deploy on a production system.
      • Dependency control

        • Software can be developed, built and tested in a chroot populated only with its expected dependencies. This can prevent some kinds of linkage skew that can result from developers building projects with different sets of program libraries installed.
      • Compatibility

        • Legacy software or software using a different application binary interface must sometimes be run in a chroot because their supporting libraries or data files may otherwise clash in name or linkage with those of the host system.
      • Recovery

        • Should a system be rendered unbootable, a chroot can be used to move back into the damaged environment after bootstrapping from an alternate root file system (such as from installation media, or a Live CD).
      • Privilege separation

        • Programs are allowed to carry open file descriptors (for files, pipelines and network connections) into the chroot, which can simplify jail design by making it unnecessary to leave working files inside the chroot directory. This also simplifies the common arrangement of running the potentially vulnerable parts of a privileged program in a sandbox, in order to pre-emptively contain a security breach. Note that chroot is not necessarily enough to contain a process with root privileges.
  • Cgroups

    • Cgroups)is a Linux kernel feature to limit, account, and isolate resource usage (CPU, memory, disk I/O, etc.) of process groups.
    • Cgroups also provides namespace isolation to completely isolate application’s view of the operating environment, including process trees, network, user ids and mounted file systems.
  • LXC (LinuX Containers)

    • LXC provides operating system-level virtualization through a virtual environment that has its own process and network space, instead of creating a full-fledged virtual machine.
    • The Linux kernel comprises cgroups for resource isolation (CPU, memory, block I/O, network, etc.) that does not require starting any virtual machines.
    • LXC combines cgroups and namespace support to provide an isolated environment for applications. Docker can also use LXC as one of its execution drivers, enabling image management and providing deployment services.
  • CoreOS

    • CoreOS is an open source lightweight operating system based on the Linux kernel and designed for providing infrastructure to clustered deployments, while focusing on automation, ease of applications deployment, security, reliability and scalability. As an operating system, CoreOS provides only the minimal functionality required for deploying applications inside software containers, together with built-in mechanisms for service discovery and configuration sharing.

Linking Multiple Apps

Testing With Logan

Receive Message Chain

receive_message_chain
1
2
allow(obj).to receive_message_chain(:foo, :bar).and_return(double)
expect(obj.foo.bar).to receive(:bazz).with(/adfads/)

Yielding multiple variables

  • allow(fake_container).to receive(:attach).and_yield("stdout", "some message\n")

expect_any_instance_of

Testing Sidekiq

  • Mike Perham did a nice job documenting the testing options for workers.

    Detecting pending migrations

  • A neat little trick to see if there are pending migrations rake db:migrate:status. This must have been built into rails because I see a message every time I haven’t run a migration and I am running my test suite. It’s cool nonetheless. Source

Root Route Takes Parameters

Looking for a hacky way to hard code your root path?

Look no further: root to: 'controller#action', hello_id: 1, finder_id: 1, laser_id: 1, sharks_id: 4 via

Stubbing Out Faraday

Webmock to disable net connections

Rspec Mocks

To stub it out I could either

These Both Work
1
2
3
4
5
6
7
before do
  allow(MyService).to receive(:new) { double }
end

before do
  allow_any_instance_of(MyService).to receive(:publish)
end

Really cool. The allow_any_instance_of() is pretty sweet to reference an unnamed instance of a class. Pretty sweet.

Web Sockets Versus Nginx Push State Versus Action_controller::live

The Decision

Nginx Push State

https://gist.github.com/loganhasson/c8bfff2767ea74187cf0

Enter Heroku

Clearly keeping a threaded server open with the warning below is not ideal:

Long-polling and streaming responses

Cedar supports HTTP 1.1 features such as long-polling and streaming responses. An application has an initial 30 second window to respond with a single byte back to the client. However, each byte transmitted thereafter (either received from the client or sent by your application) resets a rolling 55 second window. If no data is sent during the 55 second window, the connection will be terminated.

If you’re sending a streaming response, such as with server-sent events, you’ll need to detect when the client has hung up, and make sure your app server closes the connection promptly. If the server keeps the connection open for 55 seconds without sending any data, you’ll see a request timeout.

  • There are some solutions out there:
    1. Like
    2. Or

Presenter Objects

From our PR thread

  • A presenter object is a simply a PORO (plain ol’ ruby object), constructed by the controller out of the data of one or more models, whose attributes serve the view layer. So in our case we give a view a LessonPresenter that has a css_class attribute and remove all decision making from the view layer (which is the ideal goal).

  • It’s not a “service” object, it’s a presenter so it would go in the presenters folder. This is also sometimes called a “view model” or a “view object”. The word “presenter” is overloaded a lot.

  • This an interesting read on a few model refactoring patterns:

  • So instead of a collection of Lessons at the view level, you’d be dealing with a collection of LessonPresenters or similar. Alternatively, you can just put that method on the lesson object itself, which is simpler and more straightforward but not strictly Single Responsibility Principle/Seperation of Concerns/Model View Controller compliant. tradeoffs.

Is it a terrible idea to have LessonPresenter inherit from Lesson?

A: Strictly speaking in terms of OO, inheritance describes an “is-a” relationship, and you can’t say that a lessonpresenter is a lesson, so introducing an inheritance chain is probably inappropriate. There is some duplication to this pattern. Typically a viewmodel exposes only the attributes needed to satisfy the needs of the view, and you’d fill them in from the corresponding model on construction.

While this seems on the surface to violate DRY (and be duplicate work), i’d argue that it’s no more repetition than creating factories with the same attributes as models. Separate objects for separate purposes.

You could get away with hanging a lesson off of the presenter so that you could access it at the view level, but that’s a law of demeter violation and breaks encapsulation.

You could do the method_missing bit and delegate to the object. that’s slick and rubyish. Where that falls apart though is implementing this pattern across more than one model. Because we’re not really building a “presenter for a lesson”, we’re building a presentation object for a view that represents the model data behind it.

Already this answer is complicated, but there’s just always a lot of decisions that go into making architectural choices. It may be the case that for this one thing, creating a method on the Lesson itself is the “simplest thing that could possibly work” and satisfies one of our tenets of agile, and then we delay the big architectural choice until we need a second or third thing.

I support whichever choice you make (probably) as long as you have unit tests to support later refactoring :smile_cat: