mmag

ハマったことメモなど

知らなかった、と言ったな。あれは嘘だ。

はい。

先日、Ecto.Changeset.change/2 知らなかった - mmagというエントリを書いたのですが、前に自分が書いたコードでchange/2使ってました。はい、知ってました。

例えば、UserOrganizationmany_to_manyな関係にあるとします。あるユーザを、ある団体に入れたいとしましょう。

user = Repo.get!(User, 1)
org  = Repo.get!(Organization, 1)

Ectoではこういうとき、put_assoc/4を使って以下のようにやる方法が用意されています。

user
|> Repo.preload(:organizations)
|> Ecto.Changeset.change
|> Ecto.Changeset.put_assoc(:organizations, [org])
|> Repo.update

userorganizationsorgを入れた上で、userupdateするという感じです。このときのorganizationsにあたるassociationはpreloadしておく必要があります。忘れていても、エラーメッセージが結構わかりやすく教えてくれたりもしますが。

Ecto.Changeset.change/2 知らなかった

Ectoのmany_to_manyのドキュメントを読んでいたら、使用例の中でEcto.Changeset.change/2という関数が使われていました。

構造体からchangesetをつくってくれる関数なようです。知らなかった。struct入れてもchangeset入れてもいいみたい。キャストやバリデーション無しで変更を入れたいときに使うのじゃ、とのこと。

user = Repo.get(User, 1)

changeset = Ecto.Changeset.change(user)

changeset = Ecto.Changeset.change(user, %{name: "john"})

changeset = Ecto.Changeset.change(changeset, %{age: user.age + 1})

postcssで書いたものをwebpackで1つのまとめる

こういうやつ、いつもハマって時間使うので書いておきます。

postcssが〜とかではなく、extract-text-webpack-pluginがどんなやつなのか分かってなかったのが問題でした。これを使うと各loaderでコネコネした結果を指定したファイルに吐き出してくれます。これを使わずテキトーにやると、HTMLに謎の<style>が生成されて、えっ、productionでもこういう感じなの...と不安になります。

// webpack.config.js

var ExtractTextPlugin = require("extract-text-webpack-plugin");
var CopyWebpackPlugin = require("copy-webpack-plugin");

var extractCSS = new ExtractTextPlugin("css/app.css");

module.exports = {
  entry: [
    "./web/static/js/app.js",
    "./web/static/css/app.css",
  ],
  output: {
    path: "./priv/static",
    filename: "js/app.js",
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel",
        query: {
          presets: ["es2015"],
        },
      },
      {
        test: /\.css$/,
        loader: extractCSS.extract(  # この辺がよくわからんかった
          'style-loader',
          'css-loader',
          'postcss-loader',
        )
      },
    ],
  },
  postcss: [],
  plugins: [
    extractCSS,
    new CopyWebpackPlugin([{from: "./web/static/assets"}]),
  ],
};