スポンサーサイト

0

    一定期間更新がないため広告を表示しています


    • 2014.12.23 Tuesday
    • -
    • -
    • -
    • -
    • -
    • by スポンサードリンク

    symfony1.4.x + sfDoctrinePluginで失敗しないmigrationのやり方 - Symfony Advent Calendar JP 2011 day 19

    0
      Symfony Advent Calendar JP 2011 19日目です。
      昨日は@co3kさんでした。


      doctrineのmigration機能、使ってますか?

      そもそもsymfony+doctrineのmigrationとは何かというと、一旦決めたDBスキーマが後から変更になったとき、テーブル作成・カラムの追加/変更などの作業を一元管理できる仕組みです。(RubyOnRails由来)
      例えばカラムが追加になった時、プロジェクト側で持っているスキーマ情報(schema.yml)を変更した時に、手動で(コマンドやphpmyadmin等から)実際のDBテーブルにもカラムの追加を反映するのはなかなか大変です。追加カラムが1個ならまだしも、何個もあったり、複数テーブルに渡っていたりするととても面倒です。
      面倒な作業=ミスが発生しやすい のでできるだけ手動でやるのは避けたいですよね。

      これを解決してくれるのがdoctrineのmigration機能です。
      スキーマ情報を変更するだけで、あとはコマンドを手順通り発行すれば実際のDBテーブルに変更を反映してくれます。

      既に使っている人にはもはや手放せないぐらい便利な(?)機能なのですが、あまり日本語ドキュメントがないので、この機会に書いてみることにしました。

      ■ケース1:DBスキーマを変更する(基本の使い方)
      下のようなプロジェクトの初期schema.ymlがあったとします。


      後からやっぱり商品説明もDB管理したいとなったとき、migrationの出番です。

      まず、schema.ymlを変更してdescriptionを追加します。


      スキーマの差分を自動生成するコマンドを実行します。
      ./symfony doctrine:generate-migrations-diff

      lib/migration/doctrineにmigrationクラスが自動的に生成されています。

      (※生成されたクラスの中身を見れば、別に自動生成に頼らずとも手動でも書こうと思えば書けるクラスだということはわかると思います→ケース3参照)

      いよいよmigrationを実行します。
      ./symfony doctrine:migrate 1
      →productテーブルの構造が変更され、descriptionカラムが追加されます。
      ※オプションの1はバージョン番号です。未指定の場合、lib/migration/doctrineにあるうち、最新のバージョンまで順番に全て実行されます。

      model,form,filterはdescriptionを扱えるように生成し直す必要があります。
      ./symfony doctrine:build --model --forms --filters
      (form,filterを使ってない時は--modelだけでOK)

      これでDBスキーマ変更が完了してしまいます!


      migrationのバージョン番号は、migration_versionというテーブルが勝手に作られ、その中のversionというカラムで管理されます。
      一旦descriptionを足した後で不具合等が確認され「やっぱりちょっとリリース待って!」という事態になった時は、バージョンを下げることができます。
      ./symfony doctrine:migrate 0
      →descriptionカラムが削除されます。modelの再生成をしてしまっていたら、再々生成の必要があります。
      ※オプションの0はバージョン番号です。

      もし一度追加したカラムを永久的に削除する(一旦下げるのではなく)場合は、バージョンを下げるのではなくカラム削除のmigrationを新たに行うほうが無難でしょう。



      なお、実行する環境と実行する人の手際によって、ほんのわずかの間ですがmodelと実際のDBの間に齟齬が発生します。そのため、あるはずのカラムがない状態になる等で運用中のシステム上でエラーが発生する可能性があります。
      が、万一ダウンタイムになっても、手動でDBを変更しながらmodelを再生成する場合に比べて最小限で済むと思われます。

      対策としては、
      ・カラムの削除だけを行うmigrationの場合は上記の手順を逆にして、先にmodelの再生成を行ってからdoctrine:migrateを実行する
      ・カラムの追加だけを行うmigrationの場合は先にdoctrine:migrateを実行してからmodelを再生成する
      ・カラムの追加と削除が同時に発生する要件でも、敢えてschema.ymlの編集を2回に分けて、カラム追加とカラム削除のmigrationの実行を分ける(カラム追加のmigrate→model再生成→カラム削除のmigrate→model再生成のような手順で行う)
      が考えられます。
      この回避策は一般的なものですので、個々のケースに合わせて考えて実行してみてください。


      ■ケース2:migrationが積み重なったプロジェクトを新規にセットアップし、さらにDBスキーマを変更する(実際のプロジェクトでの使い方)

      ケース1を経てリリースされたシステムをサーバー移転等で一から再構築した場合を考えてください。
      ./symfony doctrine:build --all
      で構築すると、最初から既に変更済みのschema.ymlでDBテーブルが作成されます。
      そのまま運用する場合には問題ないのですが、更にDBテーブルの変更が発生すると再びmigrationの出番です。
      descriptionだけでなく、社内用の備考memoもDB管理することになったとして考えてみましょう。

      まず、ケース1と同じようにschema.ymlを変更し、差分自動作成のコマンドを実行します。

      ./symfony doctrine:generate-migrations-diff

      lib/migration/doctrineにVersion2クラスが生成されます。(ここまでケース1と同じですね)


      さて、ここで問題になるのが、既にversion1までの内容が適用済みのDBに対して、バージョン1→バージョン2だけのmigrationを行いたいのですが、このサーバーではmigrationを行ったことがないため、migration_versionテーブルがまだありません。つまり、doctrineはバージョン0と認識してしてしまう状態です。

      が、心配は要りません。黙ってバージョン2へのmigrationを行いましょう。
      ./symfony doctrine:migrate 2

      やはり、予想通りに(?)エラーが出ます。

      - SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'descrip
      tion'. Failing Query: "ALTER TABLE product ADD description TEXT"

      が、エラーになっても止まらずに指定したバージョンまで順に進めてくれるため、問題なくDBテーブルの変更自体は完了します。
      modelの再生成を行えば、DBテーブルの変更は完了となります。

      ケース2ではもう1個しておいた方が良い作業があります。
      この段階まで終わった状態でmigration_versionテーブルを見ると、versionカラムが空になっていると思います。
      versionカラムに適用済みにしたバージョン番号(このケースの場合だと2)を手動で(コマンド又はphpmyadmin等で)入れます。
      こうしておくと、更にもう1回以上DBスキーマ変更が発生した時でも、今度はバージョン2まで適用済みとして認識させることができます。
      ※これを怠ると次もバージョン0から実行されてしまい、doctrine:migrate実行時にSQLのエラーを見ることになります。


      影響がないとはいえ一時でもエラーを見たくない、という人は、migrationの前に自分でmigration_versionテーブルを作って、現在のバージョンを正しく認識させることでエラー表示を回避できます。
      migration_versionテーブルを作り、integerでversionカラムを作ります。index等は要りません。
      既に適用済のバージョン番号(このケースの場合だと1)を値としてversionに入れてから
      ./symfony doctrine:migrate 2
      を実行しましょう。今度はエラーなくmigrationが完了するはずです。


      ■ケース3:behaviorのmigration
      便利なdoctrineのbehaviorですが、デフォルトのbehavior(Timestampable,NestedSet等)でなく自作のものを使っている時に、behaviorで追加しているカラム自体が変更になった時のmigrationは注意が必要です。
      具体的には、doctrine:generate-migrations-diffコマンドではschema.ymlとmodelの間の差分のみを見るため、behaviorの変更分は自動でmigrationクラスを作ってくれないからです。

      このような場合、doctrineのmigrationを使ってDBテーブルに変更を反映するには、migrationクラスを手動で書く必要が出てきます。
      lib/migration/doctrineにversion(バージョン番号).phpファイルを作り、自分で内容を書きます。
      Version(バージョン番号)クラスは、Doctrine_Migration_Baseをextendsし、upとdownメソッドをpublicで定義すれば手動で書いてもちゃんと認識・実行されます。
      ケース1やケース2の自動生成されたVersion1,Version2クラスでカラムの追加・変更の書き方は出てきたと思いますが、他にもカラムの型を変更したりindexを足したりすることができます。
      一覧がhttp://www.doctrine-project.org/projects/orm/1.2/docs/manual/migrations/ja#%E3%83%9E%E3%82%A4%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E6%9B%B8%E3%81%8F:%E5%88%A9%E7%94%A8%E5%8F%AF%E8%83%BD%E3%81%AA%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3にありますので、実際に書き始める前に一度チェックしてみてください。



      一度わかってしまえばすごく便利なdoctrine:migrate、symfony1.4で開発する時には是非使ってみてださい^^
      Symfony2ネタが続く中、空気読まずにsymfony1.4.xネタでお送りしました☆

      明日は@fivestrさんです!


      Doctrine(1.x)でのLEFT OUTER JOIN実現方法

      0
         公式のドキュメント
        http://www.doctrine-project.org/projects/orm/1.2/docs/manual/dql-doctrine-query-language/ja#join%E3%81%AE%E6%A7%8B%E6%96%87:on%E3%82%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%89
        によると、ONキーワードでリレーション条件がカスタム指定できるようなことが書いてありますが、実際には効きませんorz

        試行錯誤の末、無理やりLEFT OUTER JOINぽいことを実行させることができたので忘れないようにメモ。
        実験しながらエラーMSGでググると、symfony公式のフォーラムでも世界各国の方々がLEFT OUTER JOINができないと悩んでいた。

        なんでONを自分で指定したいかと言うとモデルを次のように定義してあるとして、
        Able:
        columns:
        id: { type: integer(1), primary: true }
        Baker:
        columns:
        id: { type: integer(1), primary: true }
        out_class: string(4)
        out_id: integer(1)
        Cat:
        columns:
        id: { type: integer(1) }
        Bakerはout_classの値によりAbleかCatどちらかにJOIN先が変わります。
        なんでこんな変な構造にするか詳細は聞かないでください(笑

        【実験1】
        まず公式のドキュメント通りに。
        $q = Doctrine::getTable("Baker")->createQuery("b")->leftJoin("Able a ON a.id ON b.out_id");
        ⇒...FROM Baker b, Able a...
        ONどこいった??単にFROMにカンマ区切りで入れられると、SQL側でAble.idとBaker.idで勝手にJOINされちゃって都合が悪い。

        【実験2】
        公式ドキュメントにWITHというのも書いてあるので使ってみた。
        $q = Doctrine::getTable("Baker")->createQuery("b")->leftJoin("Able a ON a.id =b.out_id");
        ⇒...FROM Baker b, Able a...
        WITHどこいった??

        【実験3】
        無理を承知でINNER JOINにしてみる。Linux系OSのMySQLで、MyISAMテーブル(=外部キー制約なし)だとBaker.out_idとA.idのINNER JOINとか普通に成立した記憶が。
        $q = Dcotrine::getTable("Baker")->createQuery("b")->innerJoin("Able a ON a.id = b.out_id");
        ⇒エラー。AbleとBakerの間にリレーションが定義されてないとか何とか。まあ当然。


        ここで公式APIドキュメントを読みに行く。
        Doctrine_Query_Abstruct::leftJoin($join, $params=array())
        色々場合分けはあるが、要は最後に $this->dqlQueryPart['from']に 'LEFT JOIN '.$joinをセットする仕組みのよう。
        【実験4】
        とりあえずセットした後にちゃんとセットされているかどうかチェックしてみる。
        $q = Doctrine::getTable("Baker")->createQuery("b")->leftJoin("Able a ON a.id = b.out_id");
        var_dump($q->getDql());
        ⇒FROM Baker b LEFT JOIN Able a ON a.id = b.out_id
        ちゃんとDQLにはセットされていることが確認できた。
        が、$q->getSqlQuery()すると相変わらず FROM Baker b, Able aのみ。どうやらDQLからSQLを生成する時にONが無視されてしまう様子。

        ここでふと思い出した。Pear::DBを使ってSQLを勉強し始めた頃、FROMにテーブルを羅列してWHEREでJOIN条件書いてもほしいデータが取れてたなー。その後SQL実行速度の問題でちゃんとJOINを書くようになったんだけど。
        【実験5】
        だめもとで。
        $q = Doctrine::getTable("Baker")->createQuery("b")->addFrom("Able a")->addWhere("b.out_id = a.id");
        ⇒実験3と同じエラー。でも、$q->getSqlQuery()ではちゃんとSQLが出て来るし、それをコピペしてphpmyadminに実行させたらちゃんと想定通りのデータが出た。

        【実験6】
        実験5ではAbleのデータを入れるコンポーネント(プロパティ)がないよ!って怒られてる気がしてきた。同時にBakerとJOINするAbleまたはCatのデータはBakerに取得用のメソッドを作ってあるのでAbleのデータを最初のSELECTで取らなくてもいいよね、と考える。
        $q = Doctrine::getTable("Baker")->createQuery("b")->addFrom("Able a")->addWhere("b.out_id = a.id")->select("b.*");
        ⇒成功!!

        ここまで来るのに休み休み(家事育児やりながら^^;)で4時間近くかかってしまった(汗
        【結論】
        スマートじゃない&MySQLエンジンがんばって!なSQLだけど、上記の方法でLEFT OUTER JOINっぽいことはできることがわかりました。



        sfWidgetFormSelectCheckbox, sfWidgetFormSelectRadioの日本語value対応(何年ぶりのsf記事??

        0
          sfWidgetFormSelectCheckbox, sfWidgetFormSelectRadioでchoicesのvalue値(label値ではなく)としてマルチバイト文字列を使うと、いくつかの選択肢が表示されなくなる現象がありました。
          原因としては、inputタグを作るとき(render?)にinputタグのid値をユニークなキーとして使うらしく、そのid値はnameとvalueを「_」で繋いで作るんだけど、sfWidgetForm内でマルチバイト文字列(まぁ日本語の文字列)は「_」に変更されてしまうので、偶々複数のchoicesのvalue値の中に文字列長が同じのがあると、1つにまとまってしまうみたい。
          長々と文章で説明するより実例のほうがわかりやすいかな。

          $choices = array("ほげ"=>"ほげ", "ふが"=>"ふが");
          をcheckboxやradioのchoicesとして指定すると、出力は
          checkboxなら □ふが <input type="checkbox" name="check" value="ふが" id="check___" />&nbsp;ふが
          radioなら ○ふが <input type="radio" name="radio" value="ふが" id="radio___" />
          のみになります。つまり最後の1個だけ。

          で、これを回避するためにはid値の生成メソッド=sfWidgetForm::generateId()を下記のように変更してみました。
          /lib/vender/symfony/lib/widget/sfWidgetForm.class.php
          255行目〜オリジナル
              // remove illegal characters
              $name = preg_replace(array('/^[^A-Za-z]+/', '/[^A-Za-z0-9¥:_¥.¥-]/'), array('', '_'), $name);
          255行目〜私の修正版
              // remove illegal characters
              //$name = preg_replace(array('/^[^A-Za-z]+/', '/[^A-Za-z0-9¥:_¥.¥-]/'), array('', '_'), $name);
              $name = preg_replace('/^[^A-Za-z]+/', '', $name);
              if(preg_match('/[^A-Za-z0-9¥:_¥.¥-]/', $name)>0)
              {
                $name = md5($name);
              }
          一見してわかるとおりマルチバイト文字を「_」×文字数に置換してしまうのではなく、マルチバイト文字列を含むname + _ + value をmd5ハッシュ化してしまっただけです。
          デメリットはinputのid値を使ってCSSでデザインを指定したいときには厳しい(出力されたinputタグをみて頑張って><)ことぐらい?
          まぁ個々のinputにデザイン決めたいぐらいの時はchoicesのkey(value値として渡す値)をアスキー文字だけにして使ってください。
          今回の私の案件ように、運営者が自分でフォームの選択肢を編集する(しかも、運営者は、言語ファイル未アップでtitle, bodyとフォームのラベルが表示されたら「プログラムのコードが出ってます!!」と泡食って連絡してくるぐらい英語オンチ)とか、そういう特殊な状況じゃなければ多分使わないと思いますが。
          #そういえば、mysqlのenumってマルチバイト文字使えたっけ。enumに日本語文字列を指定して、doctrineのschemaからフォームを自動生成させたらどうなるんだろう。そういう時この修正方法が生きるかも???誰か人柱お願いします(笑)


          何年ぶりにsymfony記事を書いたんだろう、自分…。


          久しぶりにsymfonyを触ると…(汗

          0
            今日は久しぶりにsymfonyを触っています。
            というのも。
            ・ajaxを大量に使うフォームを扱う
            ・管理画面よりユーザ画面でCRUDをさせる目的(というかぶっちゃけ管理画面は無くてもいい)
            ・ユーザは基本的にビジネスユーザなので多少速度が遅くてもOK
            という理由で、symfonyを使ったシステムを組んでるから^^;

            ホントはdjangoでチャレンジしてもよかったんだけど、鯖がpython未セットアップの鯖なので、色々SSHでインスコ作業が発生するのが面倒なので、約2ヶ月ぶり?にsymfonyを使うことにしました。
            #rachoに触ってみようかな?と思ったんですが、締め切りが短い案件なので学習時間がもったいなくて。

            init-appじゃなくてstartappと打って「コマンド違うよ!」と怒られ(爆
            schema.yml書いてるのに、カラム名とオプションの間を「:」じゃなくて「=」でつないでたり(爆
            処理の最後に「;」忘れたり(爆
            その他もろもろ。
            朝から今まで色々やらかしました^^;

            それでもこれでもPHPベタ書きよりは速いです。格段に。

            今抱えてるプロジェクト(何と今5つも持ってます><)が片付いたら、ようやく1.0RC1が出たZendFrameworkに触ってみようかな^^




            django対symfony 日本語メール送信(その1 symfony編)

            0
              クライアントさんのための作業(私の手書きPHP製WEBアプリをsymfonyへ移行)が一段落したので、勉強を兼ねてdjangoでいくつかアプリを作ってみています。
              で、我々日本語話者にとって、海外製フレームワークを使うにあたっての重要な問題が…やはり発生fーー;


              WEBサイトそのものの表示・DB接続周りは、UNICODEさんのお陰で改善されてきた今日この頃ですが、問題はメールですよ、メール!日本語メール、文字化けせずに送れるか?が実用ベースに乗るかどうかの分かれ目と言っても過言じゃないかも…


              まず、symfonyの場合。
              symfony code snippetに「さこだ こうた」さんが投稿してくれたコードがあります。
              sfMailを拡張するmyMailというカスタムクラスを作り、自前でmb_convert_encodingした
              本文をつっこむというもの。
              これだと、WEBサイトの表示用言語(かつ、DBやコード自体の文字コード)としてあまり一般的ではないiso-2022-jpに、メール送信直前にエンコード変換をすることができて、日本の一般人がちゃんと読める形式のメールを送ることができます。

              ※ちなみに、厳密に言うと上記snippetのコードだけでは日本語メールは送れません。
              私が自作して使っているmbMailクラスを公開しますと…


              エラーページのカスタマイズ @symfony

              0
                先週末から1週間にわたって緊急案件をやってたので更新できませんでした^^;;

                symfonyで作ったプロジェクトをいよいよ公開する前に、エラーページをカスタマイズする必要があります。
                一般の日本人のお客様が見るページで「うーっぷす!えらーおかーど!」とか英語で書かれても意味不明なのでw

                ■その1:404エラー
                404エラーページのカスタマイズ方法@symfony BOOK 日本語版!
                http://develop.ddo.jp/symfony/book/jp/1.0/404.html

                極めて簡単です。
                myapp > settings.yml内
                all
                .actions

                ↑とコメントアウトしてある部分があるので
                error_404_module: default
                error_404_action: error404
                を適当に自作の404エラー表示用モジュール・アクションに書き換えればOK。
                面倒くさければdefaultというモジュールを作ってerror404アクションを書いてしまってもいいかも。

                ■その2:500エラー(うーっぷす!えらー)
                本家のsymfony bookにはこう書いてあります。

                Two other pages bear a symfony look and feel, and they also need to be customized before deployment to production. These pages are not in the default module, because they are called when symfony cannot run properly. Instead, you will find these default pages in the $sf_symfony_data_dir/web/errors/ directory:

                error500.php: Page called when an internal server error occurs in the production environment. In other environments (where SF_DEBUG is set to true), when an error occurs, symfony displays the full execution stack and an explicit error message (see Chapter 16 for details).
                unavailable.php: Page called when a user requests a page while the cache is being cleared (that is, between a call to the symfony clear-cache task and the end of this task execution). On systems with a very large cache, the cache-clearing process can take several seconds. Symfony cannot execute a request with a partially cleared cache, so requests received before the end of the process are redirected to this page. The unavailable.php page is also used when an application is disabled via the symfony disable command (see Chapter 16 for details).
                To customize these pages, simply create error500.php and unavailable.php pages in your application's web/errors/ directory. Symfony will use these instead of its own.


                要約すると、
                ・デフォルトのエラーページはdata/symfony/web/errors内のerror500.phpだよ!これを修正すればいいよ!
                ・もしデフォルトをいじりたくなければ、myappのwebディレクトリにerrorsディレクトリを作ってそこにerror500.phpを置けばいいよ!
                と書いてあります。(多分)

                今回、私の取り組んでるのは、一つのプロジェクト内で属性の違う2種類のお客様が動き回り、それぞれに対して違う見た目を提供する必要があので、できれば後者を使ってappごとにエラーページを使い分けたい。

                私のアプリのwebディレクトリは、/home/symfony/public_html/hoge/にあるので、hogeの下にerrorsディレクトリを作り、そこにerror500.phpとunavailable.phpを置いた。
                ここで念のためsymfony cc。

                公式マニュアルによれば、これでOKのはず。
                が、なぜかできないorz デフォルトのエラーページが表示されます…。

                仕方ないので、単に「えらーが発生しました」を白地に黒文字で書いただけのページでdata/symfony/web/errors/内のデフォルトページを上書きし、応急処置にしました。

                タイプミス?キャッシュが残ってるから?…
                色々試しましたが現時点では解決策不明でした><

                が、なぜかできないorz


                symfony routing.yml関係のメモ

                0
                  routing関係のメモ。

                  例えば
                  http://example.com/hoge/hage.html
                  にアクセスしたら
                  http://example.com/index.php/foo/bar/title/hage
                  (fooモジュールのbarアクションでtitle=hageをパラメータとして渡す)
                  としたい場合。
                  この「見た目」はSEO上重要ですし、人間の目から見ても短くていかにも静的なHTMLに見えてなかなかGoodです^^

                  ■apps→myapp→config→routing.ymlに
                  foo_bar_category_and_title: #←好きな名前をつける
                  url: /hoge/:title #「:」を付けない文字列は単なる文字列と言う意味です
                  param:
                  module:foo
                  action:bar
                  ■apps→myapp→config→settings.yml内
                  .settings
                  suffix: .html #拡張子無しでアクセスさせたい(デフォルトに戻す)場合は「.」だけにすれ元に戻ります

                  ディレクトリ構造に見せることができます。


                  multiple select boxでのhierselect(@symfony)

                  0
                    現在開発中のシステム、この機会に色々と機能を見直してるので、色々実験もしてます。

                    Pearを使っていた頃にはなかったmultipleセレクトボックスのhierselectなんてものを作ってみました^^;

                    基本的にはmultipleなしのhierselectと同じなんですが、ちょっとだけ違います。


                    symfonyでhierselectができる!の補足(fillin時の手当)

                    0
                      昨日のsymfonyでhierselect実現!ですが、あのままではsymfonyのフィルイン機能を使った時に不具合があるのでちょっと補足メモ。
                      #書いておかないと次のプロジェクトできっと同じところにハマるアフォな私…

                      まず、symfonyのフィルイン(fillin)機能とは、
                      1.ユーザーが間違ったデータを入力してsubmitボタンを押す(例:郵便番号の桁数違いとか)

                      2.データを受け取ったアクションが間違いに気付いて(←validate機能)、入力フォームに戻す(handleError+アクション名のメソッドを定義して、sfView::SUCCESS)

                      3.デフォルトのままではフォームの入力内容が全て消えてしまうが、それではユーザに対して不親切すぎるので、以前の入力内容を自動的にフォームに突っ込む(←これがfillin!)
                      という感じ。

                      脱線しまくりw
                      fillinを有効にするには、validate.ymlファイルで
                      fillin:
                      enable: on
                      と書けば良い。(アプリ全体のfilters.ymlファイルに書く方法もあるけど省略。)
                      fillinを受ける側のフォームは、各input_tag等のフォームヘルパー関数の引数2つ目(デフォルト値を入れるところ)をnullにする。
                      ※私は最初「''」を指定した状態でフィルインできませんでした。object系のフォームヘルパーを使ってDBからデフォルト値を持ってきてる場合はどうなるんだろう??今度実験してみよう…

                      で、このフィルイン時に…


                      symfony+Ajaxでhierselectを実現!

                      0
                        えーっとついさっきsymfonyにはhierselectがない!と騒いでましたが、解決しました(^^;
                        ちゃんと調べて実験してからメモ書きましょう。。。>自分

                        参考にしたのはsymfony本家のCode Snippetにあったコード。
                        Code Snippetは「色々な人がsymfonyを使ってこんなことできたよ!」を晒してくれる場所です。

                        ⇒⇒Select with a onChange remote function option
                        そのまんま、onChangeとremote_functionを使って連動するセレクトBOXを作る方法。
                        ちなみに、javascript無効なブラウザでも大丈夫なように手当がされています。(多分)

                        私のコードは以下の通りです。
                        #gdgdで恥ずかしいけど誰かの役に立つことを願って公開しておきます。
                        続きを読む >>



                        PR

                        calendar

                        S M T W T F S
                           1234
                        567891011
                        12131415161718
                        19202122232425
                        262728293031 
                        << March 2017 >>

                        twitter

                        selected entries

                        categories

                        archives

                        recent comment

                        • 結局CodeIgniter用汎用Modelクラス&汎用CRUDスクリプトを書きました
                          プログラマー
                        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
                          よし
                        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
                          ななうぇぶ
                        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
                          よし
                        • icu4.4以上が用意できないサーバーでSymfony2.3以上を使う方法
                          よし
                        • WindowsのPCで開発するphperがxhprofを使う方法
                          ななうぇぶ
                        • WindowsのPCで開発するphperがxhprofを使う方法
                          川本
                        • [バッドノウハウ]Symfony2で別テーブルの集計項目を一覧に含めたいとき
                          よし
                        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
                          77web
                        • Symfony Advent Calendar JP 2012 day 14 - vendorをcomposerで管理しているプロジェクトにcomposerを使わずにバンドルを追加したときのautoloadの書き方
                          ktz

                        recent trackback

                        • HTMLの表(TABLE)のセル(TD)に斜線を引くjavascriptライブラリ slash.js 作っちゃいました
                          常山日記
                        • django対symfony 日本語メール送信(その1 symfony編)
                          CPA-LABテクニカル
                        • CodeIgniterでユーザー認証
                          されどLAMPな日々
                        • 久々にdjangoを最新版にしたらHTMLがエスケープされちゃった!!(解決済み)
                          常山日記
                        • FastCGIを諦めてmod_pythonを使う。Apacheのアップグレード
                          サーバー用語集
                        • さくらインターネット、sqlite3でdjango@CGI版を使う際の設定メモ
                          常山日記
                        • さくらインターネット スタンダードプランでdjango使ってる方、DBは?
                          mitszoの日記
                        • python多次元リストをsort(並べ替え)する方法?
                          mitszoの日記
                        • フォームから送信した値とrequest.POSTの挙動($_POST@PHPとの比較)
                          Humming Via Kitchen
                        • 日本語テキストをtruncate@django(Python全般にも??)
                          常山日記

                        recommend

                        links

                        profile

                        search this site.

                        others

                        mobile

                        qrcode

                        powered

                        無料ブログ作成サービス JUGEM