Code Monkey home page Code Monkey logo

habits's Introduction

Build Status Code Climate Test Coverage

What is this?

This is the source code for the Ruby on Rails app which powers stevegrossi.com. Its duties include managing the books I've read, posts I've written, which can be optionally be about a book or an external link, plus a handful of informational pages and redirects.

habits's People

Contributors

schlenks avatar stevegrossi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

habits's Issues

Replace ex_machina with my own simple factories

example from http://blog.plataformatec.com.br/wp-content/uploads/2017/05/whats-new-in-ecto-2-1.pdf:

defmodule MyApp.Factory do
  alias MyApp.Repo

  # Factories
  def build(:post) do
    %MyApp.Post{
      title: "hello world"
    }
  end
  
  def build(:comment) do
    %MyApp.Comment{
      body: "good post"
    }
  end
  def build(:post_with_comments) do
    %MyApp.Post{
      title: "hello with comments",
      comments: [
        build(:comment, body: "first"),
        build(:comment, body: "second")
      ]
    }
  end
  def build(:user) do
    %MyApp.User{
      email: "hello #{System.unique_integer()}",
      username: "hello #{System.unique_integer()}"
    }
  end
  
  # Convenience API
  def build(factory_name, attributes) do
    factory_name |> build() |> struct(attributes)
  end
  
  def insert!(factory_name, attributes \\ []) do
    Repo.insert! build(factory_name, attributes)
  end
end

assoc vs. ids: should contexts reach into other contexts?

assoc

def list_habits(%Account{} = account) do
  account
  |> assoc(:habits)
  |> Repo.all()
end
  • Requires import Ecto, only: [assoc: 2]
  • ๐Ÿ‘Ž Pattern-matching (optional, but ideal) requires reference to another context's schema, Accounts.Account

ids

def list_habits(account_id) when is_integer(account_id) do
  account
  |> where(account_id: ^account_id)
  |> Repo.all()
end
  • Requires import Ecto.Query
  • ๐Ÿ‘ A tiny bit more efficient, since we only need the ID from the database, not the full record
  • ๐Ÿ‘Ž Requires duplicating (potentially complex, with joins) relationship logic

In-Context associations?

Inspired by this forum post.

def list_habits(account_id) when is_integer(account_id) do
  %Habits.Account{id: account_id} # not Accounts.Account
  |> assoc(:habits)
  |> Repo.all()
end

# which requires

defmodule Habits.Habits.Account do
  use Ecto.Schema

  schema "accounts" do
    has_many(:habits, Habit)
  end
end
  • ๐Ÿ‘ Avoids potential duplication of the account <-> habits association logic within this context
  • ๐Ÿ‘ Habits.Account could be anything, potentially more context-specific like Habits.Owner
  • ๐Ÿ‘ A tiny bit more efficient, since we only need the ID from the database, not the full record
  • ๐Ÿ‘Ž Another file?

GeoIP always returns unknown location

When requesting assets, the Heroku logs show a fwd attribute matching my public IP address:

2017-01-08T13:05:09.642080+00:00 heroku[router]: at=info method=GET path="/css/app-d4e8768585bc21a0a526a605e0070824.css?vsn=d" host=elixir-habits.herokuapp.com request_id=c306725f-6d9d-401b-b20b-dabedc0ecdd5 fwd="76.238.169.213" dyno=web.1 connect=0ms service=1ms status=200 bytes=5463

Apparently, this corresponds to the value of the X-Forwarded-For header, which is missing for API requests such as POST /sessions:

2017-01-08T13:10:26.764307+00:00 app[web.1]: 13:10:26.764 request_id=559a8e9c-c2ef-4973-b39f-7c6025b167e3 [info] POST /api/v1/sessions

As a result, when GeoIP inspects the conn to extract the location, it's reading a private IP address that it (obviously) can't determine the location of:

%GeoIP.Location{city: "", country_code: "", country_name: "", ip: "10.149.111.149", latitude: 0, longitude: 0, metro_code: 0, region_code: "", region_name: "", time_zone: "", zip_code: ""}

For this reason, /sessions currently always shows only the default location of "Earth". I'm not sure if this requires a Phoenix fix, a client-side fix, or something on Heroku's end.

Fix the build ๐Ÿ˜ฅ

Curiously, the build for #22's branch passed, but began failing once merged into master:

screen shot 2018-11-04 at 5 56 16 am

So that's a clue... ๐Ÿค”

Achievements, e.g. 1000 total check-ins, 100 check-ins per habit, 7 days in a row, etc.

I'm thinking at least two kinds of achievements, with some examples:

  • Account-level achievements
    • counts, e.g. 1000 Total Check-Ins
    • habit counts, e.g. add 5, 10 habits
    • great day: check into every habit (with a minimum, so not 1) in a single day
    • aggregate achievements, e.g. check into every habit 100 times
  • Habit-level achievements
    • counts, e.g. 1000 Check-Ins for a given habit
    • longest streak, e.g. streak of 100

Most of these (the count-based ones) can be calculated on the fly, but concepts like "check into every habit one day" will require storing achievements somewhere, so they persist once granted. Imagine checking into all 5 habits and unlocking "great day" only to see it disappear later on once you add a 6th habit.

And while I'm not too concerned about performance, the aggregate achievements could get quite slow if the individual habit-level achievements aren't cached/stored somewhere. We'll see.

Heroku build fails

I tried spinning it up, using the nice little button, but it fails complaining about the Elixir version.

I don't know why but it fetches Elixir 1.7.12 and then fails because requires 1.9.

Any help/idea?
Thanks


-----> Elixir app detected

-----> Will export the following config vars:

DATABASE_URL

MIX_ENV

SECRET_KEY_BASE

       * MIX_ENV=prod

-----> Checking Erlang and Elixir versions

       Will use the following versions:

       * Stack heroku-18

       * Erlang 21.1.1

       * Elixir 1.7.2 

-----> Stack changed, will rebuild

-----> Fetching Erlang 21.1.1 from https://s3.amazonaws.com/heroku-buildpack-elixir/erlang/cedar-14/OTP-21.1.1.tar.gz

-----> Installing Erlang 21.1.1 (changed)

-----> Fetching Elixir v1.7.2 for OTP 21 from https://repo.hex.pm/builds/elixir/v1.7.2-otp-21.zip

-----> Installing Elixir v1.7.2 (changed)

-----> Installing Hex

* creating /app/.mix/archives/hex-0.20.1

-----> Installing rebar

* creating /app/.mix/rebar

* creating /app/.mix/rebar3

-----> Fetching app dependencies with mix

Resolving Hex dependencies...

Dependency resolution completed:

Unchanged:

  bcrypt_elixir 2.0.3

  cachex 2.1.0

  certifi 2.5.1

  comeonin 5.1.2

  connection 1.0.4

  cowboy 2.6.3

  cowlib 2.7.3

  db_connection 2.1.1

  decimal 1.8.0

  ecto 3.2.1

  ecto_sql 3.2.0

  elixir_make 0.6.0

  eternal 1.2.1

  geoip 0.1.2

  gettext 0.13.1

  hackney 1.15.1

  httpoison 0.13.0

  idna 6.0.0

  jason 1.1.2

  metrics 1.0.1

  mime 1.3.1

  mimerl 1.2.0

  parse_trans 3.3.0

  phoenix 1.4.10

  phoenix_ecto 4.0.0

  phoenix_html 2.13.3

  phoenix_pubsub 1.1.2

  plug 1.8.3

  plug_cowboy 2.1.0

  plug_crypto 1.0.0

  plug_x_forwarded_for 0.1.0

  poison 3.1.0

  postgrex 0.15.1

  ranch 1.7.1

  secure_random 0.5.1

  ssl_verify_fun 1.1.4

  telemetry 0.4.0

  unicode_util_compat 0.4.1

* Getting bcrypt_elixir (Hex package)

* Getting plug_cowboy (Hex package)

* Getting geoip (Hex package)

* Getting gettext (Hex package)

* Getting phoenix (Hex package)

* Getting phoenix_html (Hex package)

* Getting phoenix_ecto (Hex package)

* Getting ecto_sql (Hex package)

* Getting jason (Hex package)

* Getting plug_x_forwarded_for (Hex package)

* Getting postgrex (Hex package)

* Getting secure_random (Hex package)

* Getting connection (Hex package)

* Getting db_connection (Hex package)

* Getting decimal (Hex package)

* Getting ecto (Hex package)

* Getting telemetry (Hex package)

* Getting plug (Hex package)

* Getting mime (Hex package)

* Getting plug_crypto (Hex package)

* Getting phoenix_pubsub (Hex package)

* Getting cachex (Hex package)

* Getting httpoison (Hex package)

* Getting poison (Hex package)

* Getting hackney (Hex package)

* Getting certifi (Hex package)

* Getting idna (Hex package)

* Getting metrics (Hex package)

* Getting mimerl (Hex package)

* Getting ssl_verify_fun (Hex package)

* Getting unicode_util_compat (Hex package)

* Getting parse_trans (Hex package)

* Getting eternal (Hex package)

* Getting cowboy (Hex package)

* Getting cowlib (Hex package)

* Getting ranch (Hex package)

* Getting comeonin (Hex package)

* Getting elixir_make (Hex package)

-----> Copying hex from /app/.mix/archives/hex-0.20.1

-----> Compiling

** (Mix) You're trying to run :habits on Elixir v1.7.2 but it has declared in its mix.exs file it supports only Elixir ~> 1.9

 !     Push rejected, failed to compile Elixir app.

 !     Push failed```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.