<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Groove Labo</title>
	<atom:link href="http://labo.opengroove.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://labo.opengroove.com/blog</link>
	<description>株式会社オープングルーヴの開発者のブログ</description>
	<lastBuildDate>Tue, 28 Sep 2010 06:09:57 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Railsのdatetime_selectの保存の仕組みを調べてみる</title>
		<link>http://labo.opengroove.com/blog/2010/09/28/rails%e3%81%aedatetime_select%e3%81%ae%e4%bf%9d%e5%ad%98%e3%81%ae%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e8%aa%bf%e3%81%b9%e3%81%a6%e3%81%bf%e3%82%8b/</link>
		<comments>http://labo.opengroove.com/blog/2010/09/28/rails%e3%81%aedatetime_select%e3%81%ae%e4%bf%9d%e5%ad%98%e3%81%ae%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e8%aa%bf%e3%81%b9%e3%81%a6%e3%81%bf%e3%82%8b/#comments</comments>
		<pubDate>Tue, 28 Sep 2010 06:04:02 +0000</pubDate>
		<dc:creator>sugimoto</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=650</guid>
		<description><![CDATA[sugimotoです。 Ruby on Rails にはいろいろ便利な機能がありますが、前から便利だけど微妙。。と思っているのが、date_select や datetime_select です。どちらも ActionView::Helpers::DateHelper のmethod で日付入力を簡単に作れますが、年月日のプルダウン入力はちょっと。。。という感じです。 ただ、この入力、Modelのdate,datetime なカラムにそのまま突っ込んで保存してしまえるのがとっても便利です。Post.published_at というカラムに params = { :post => { :published_at(1i) => "2010", :published_at(2i) => "09", :published_at(3i) => "28", :published_at(4i) => "15", :published_at(5i) => "20" } } みたいな感じでcontrollerにパラメータが渡されますが、 post = Post.new(params[:post]) とするだけで、post.published_at = &#8217;2010-09-28 15:20&#8242; なレコードができてしまいます。 前置きが長くなりましたが、この仕組を調べてみました。 なお、今回例示したソースは公開時のtrunk を参照しています。 仕組みを調べてみる まずはレコードを作成する場所、つまり、 ActiveRecord::Base::initialize を見てみます。 def initialize(attributes [...]]]></description>
			<content:encoded><![CDATA[<p>
sugimotoです。
</p>

<p>
Ruby on Rails にはいろいろ便利な機能がありますが、前から便利だけど微妙。。と思っているのが、date_select や datetime_select です。どちらも ActionView::Helpers::DateHelper のmethod で日付入力を簡単に作れますが、年月日のプルダウン入力はちょっと。。。という感じです。
</p>

<p>
ただ、この入力、Modelのdate,datetime なカラムにそのまま突っ込んで保存してしまえるのがとっても便利です。Post.published_at というカラムに
</p>

<pre>
params = {
    :post => {
        :published_at(1i) => "2010",
        :published_at(2i) => "09",
        :published_at(3i) => "28",
        :published_at(4i) => "15",
        :published_at(5i) => "20"
     }
}
</pre>

<p>
みたいな感じでcontrollerにパラメータが渡されますが、
</p>

<pre>
post = Post.new(params[:post])
</pre>

<p>
とするだけで、post.published_at = &#8217;2010-09-28 15:20&#8242; なレコードができてしまいます。
</p>

<p>
前置きが長くなりましたが、この仕組を調べてみました。
なお、今回例示したソースは<a href="http://github.com/rails/rails/blob/master/activerecord/lib/active_record/base.rb">公開時のtrunk</a> を参照しています。
</p>

<h3>仕組みを調べてみる</h3>

<p>
まずはレコードを作成する場所、つまり、 ActiveRecord::Base::initialize を見てみます。
</p>

<pre class="">
       def initialize(attributes = nil)
        @attributes = attributes_from_column_definition
        @attributes_cache = {}
        @new_record = true
        @readonly = false
        @destroyed = false
        @marked_for_destruction = false
        @previously_changed = {}
        @changed_attributes = {}

        ensure_proper_type

        if scope = self.class.send(:current_scoped_methods)
          create_with = scope.scope_for_create
          create_with.each { |att,value| self.send("#{att}=", value) } if create_with
        end
        self.attributes = attributes unless attributes.nil?

        result = yield self if block_given?
        _run_initialize_callbacks
        result
      end
</pre>

<p>
どうやら、受渡されたattributes を self.attributes=(attributes) でいれているだけですね。
では self.attributes=(v) では何をしているんでしょうか。
</p>

<pre>
      def attributes=(new_attributes, guard_protected_attributes = true)
        return unless new_attributes.is_a?(Hash)
        attributes = new_attributes.stringify_keys

        multi_parameter_attributes = []
        attributes = sanitize_for_mass_assignment(attributes) if guard_protected_attributes

        attributes.each do |k, v|
          if k.include?("(")
            multi_parameter_attributes < < [ k, v ]
          else
            respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
          end
        end

        assign_multiparameter_attributes(multi_parameter_attributes)
      end
</pre>

<p>
"(" が付いた attribute を複数パラメータの属性として次のような配列を作成し、 assign_multiparameter_attributes に渡しています。
</p>

</pre><pre>
[
    ["published_at(1i)", "2010"],
    ["published_at(2i)", "09"],
    ["published_at(3i)", "28"],
    ["updated_at(1i)", "2010"],
    ["updated_at(2i)", "09"],
    ["updated_at(3i)", "28"],
    ["updated_at(4i)", "15"],
    ["updated_at(5i)", "10"],
    ["published_at(4i)", "15"],
    ["published_at(5i)", "10"],
]
</pre>

<p>
では、次にassign_multiparameter_attributes を見てみます。
</p>

<pre>
      def assign_multiparameter_attributes(pairs)
        execute_callstack_for_multiparameter_attributes(
          extract_callstack_for_multiparameter_attributes(pairs)
        )
      end
</pre>

<p>
method名から察するに、一度パラメータを展開して、それを処理しているようです。展開のmethodはどんな処理でしょう。
</p>

<pre>
      def extract_callstack_for_multiparameter_attributes(pairs)
        attributes = { }

        for pair in pairs
          multiparameter_name, value = pair
          attribute_name = multiparameter_name.split("(").first
          attributes[attribute_name] = [] unless attributes.include?(attribute_name)

          parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
          attributes[attribute_name] < < [ find_parameter_position(multiparameter_name), parameter_value ]
        end

        attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } }
      end
</pre>

<p>
published_at(2i) のような名前から attributes["published_at"] という配列を作成して、(1i), (2i), (3i) などの値とセットで配列に積んでいっています。
さらに、名前でhashになった attributes を名前ごとにソートしています。
次のような hash が出来上がります。
</p>

<p>ソート前 - 1つ目の要素が文字列のまま渡されているので、xxxx(11i) みたいなのがあると並び替えを間違える気がしますが、どうなんでしょうね。。。
</p>

</pre><pre>
attributes = {
    "publised_at" => [["1", 2007], ["3", 28], ["4", 15], ["5", 10], ["2", 9], ],
    "updated_at" => [["1", 2007], ["3", 28], ["4", 15], ["5", 10], ["2", 9], ],
}
</pre>

<p>ソート後 (1つ目の要素でソートされ、2つ目の要素で collect された)
</p>

<pre>
attributes = {
    "publised_at" => [2007, 9, 28, 15, 10 ],
    "updated_at" => [2007, 9, 28, 15, 10 ],
}
</pre>

<p>
type_cast_attribute_value, find_parameter_position の2つのメソッドは名前から何をしているかなんとなく想像がつきますが、一応見てみます。
</p>

<pre>
      def type_cast_attribute_value(multiparameter_name, value)
        multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
      end
</pre>

<p>
xxxx(1i) のような名前のパラメータを to_i でtype cast した値を返します。どうやら、xxxx(1f) のような名前にすると Float にcastするようです。
</p>

<pre>
      def find_parameter_position(multiparameter_name)
        multiparameter_name.scan(/\(([0-9]*).*\)/).first.first
      end
</pre>

<p>
xxxx(1i) のようなパラメータ名から数字を取り出し、パラメータの順序を返しています。
</p>

<p>
そろそろ先が見えてきた感じがします。(1i) に従って配列にされたパラメータの処理をする execute_callstack_for_multiparameter_attributes を見てみます。
</p>

<pre>
      def execute_callstack_for_multiparameter_attributes(callstack)
        errors = []
        callstack.each do |name, values_with_empty_parameters|
          begin
            klass = (self.class.reflect_on_aggregation(name.to_sym) || column_for_attribute(name)).klass
            # in order to allow a date to be set without a year, we must keep the empty values.
            # Otherwise, we wouldn't be able to distinguish it from a date with an empty day.
            values = values_with_empty_parameters.reject { |v| v.nil? }

            if values.empty?
              send(name + "=", nil)
            else

              value = if Time == klass
                instantiate_time_object(name, values)
              elsif Date == klass
                begin
                  values = values_with_empty_parameters.collect do |v| v.nil? ? 1 : v end
                  Date.new(*values)
                rescue ArgumentError => ex # if Date.new raises an exception on an invalid date
                  instantiate_time_object(name, values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
                end
              else
                klass.new(*values)
              end

              send(name + "=", value)
            end
          rescue => ex
            errors < < AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name)
          end
        end
        unless errors.empty?
          raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
        end
      end
</pre>

<p>
なかなか長いです。。前半の klass = (....).klass でカラムの型を取ってきて、Time であれば、attributes の配列を instantiate_time_object で Date であれば、Date.new でインスタンス化して、最後に send(name + "=", value) でインスタンス化した値をカラムにセットしています。
Date でも Timeでもなかった場合は、klass.new(*values) で強引にインスタンス化しようとしますね。強気です。
</p>

<h3>最後に</h3>

<p>
なぜ、datetime_select を調べたかというと、datetime なカラムの入力フォームを作成するときに日付と時間を別にして日付部分をdatepicker にできないかな、と考えていたからでした。
</p>

<p>
xxxxx(1i) 的なパラメータ名を設定して、上記処理を通ったあとに、Date.new できる配列になれば良いってことで、やっぱり、datetime_select が生成するようなhashを作らないといけないんだな。。って感じです。
</p>
</pre>]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/09/28/rails%e3%81%aedatetime_select%e3%81%ae%e4%bf%9d%e5%ad%98%e3%81%ae%e4%bb%95%e7%b5%84%e3%81%bf%e3%82%92%e8%aa%bf%e3%81%b9%e3%81%a6%e3%81%bf%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[メモ] CentOS5 にkeepalived を設定する</title>
		<link>http://labo.opengroove.com/blog/2010/09/17/%e3%83%a1%e3%83%a2-centos5-%e3%81%abkeepalived-%e3%82%92%e8%a8%ad%e5%ae%9a%e3%81%99%e3%82%8b/</link>
		<comments>http://labo.opengroove.com/blog/2010/09/17/%e3%83%a1%e3%83%a2-centos5-%e3%81%abkeepalived-%e3%82%92%e8%a8%ad%e5%ae%9a%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Fri, 17 Sep 2010 09:46:28 +0000</pubDate>
		<dc:creator>sugimoto</dc:creator>
				<category><![CDATA[サーバーインフラ]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=647</guid>
		<description><![CDATA[wget -nd http://www.qmailtoaster.com/download/stable/daemontools-toaster-0.76-1.3.6.src.rpm yum install rpm-build rpmbuild --rebuild daemontools-toaster-0.76-1.3.6.src.rpm rpm -Uvh /usr/src/redhat/RPMS/x86_64/daemontools-toaster-0.76-1.3.6.x86_64.rpm wget -nd http://www.emaillab.org/djb/daemontools/svscan mv svscan /etc/init.d/. chmod 755 /etc/init.d/svscan 参考、、というか、そのまま: CentOS に daemontools をインストールしてみた]]></description>
			<content:encoded><![CDATA[<pre>
wget -nd http://www.qmailtoaster.com/download/stable/daemontools-toaster-0.76-1.3.6.src.rpm
yum install rpm-build
rpmbuild --rebuild daemontools-toaster-0.76-1.3.6.src.rpm
rpm -Uvh /usr/src/redhat/RPMS/x86_64/daemontools-toaster-0.76-1.3.6.x86_64.rpm
wget -nd http://www.emaillab.org/djb/daemontools/svscan
mv svscan /etc/init.d/.
chmod 755 /etc/init.d/svscan
</pre>

<ul>
  <li>参考、、というか、そのまま: <a href="http://www.ftnk.jp/~fumi/cl/2010-04-19-2.html">CentOS に daemontools をインストールしてみた</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/09/17/%e3%83%a1%e3%83%a2-centos5-%e3%81%abkeepalived-%e3%82%92%e8%a8%ad%e5%ae%9a%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ドッグフードを食べる &#8211; BTS &amp; SCM</title>
		<link>http://labo.opengroove.com/blog/2010/08/25/%e3%83%89%e3%83%83%e3%82%b0%e3%83%95%e3%83%bc%e3%83%89%e3%82%92%e9%a3%9f%e3%81%b9%e3%82%8b-bts-scm/</link>
		<comments>http://labo.opengroove.com/blog/2010/08/25/%e3%83%89%e3%83%83%e3%82%b0%e3%83%95%e3%83%bc%e3%83%89%e3%82%92%e9%a3%9f%e3%81%b9%e3%82%8b-bts-scm/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 06:55:36 +0000</pubDate>
		<dc:creator>syoji</dc:creator>
				<category><![CDATA[Wiki]]></category>
		<category><![CDATA[ソフトウェア開発]]></category>
		<category><![CDATA[ツール]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=630</guid>
		<description><![CDATA[ciklone(サイクロン)のリリース前に、自分たちが実際にプロジェクトで利用して、 ciklone(サイクロン)を改善してきました。 サイクロン開発プロジェクトの最後の6ヶ月間にソフトウェアのライフサイクルをくり返します。すべての機能を使いながら、「BTS/SCM/プロジェクト管理に必要なことができ、効率的か」、を試験してきました。 開発しながら、実際の現場で利用することで、バグがどんどん見つかったし、使いにくい点、改善すべきことがよく見えます。自分たちが作ったシステムを自分たちのプロジェクトで使う最大のメリットだと思います。 よくいわれる「ドッグフードを食べる」ことをやったことで、BTSやバージョン管理に必要な機能と必要ではない機能を切り分けることができ、開発の現場に必要なツールとして、 ciklone(サイクロン)がリリースできました。 「ドッグフードを食べる」とは、 自社で作ったソフトウェアを実際の業務で利用して、評価することです。有名なのはマイクロソフトのドッグフードです。また、Google ケータイも同様です。 シリコンバレー101[Googleケータイ販売で、Googleは何を変えたいのか?] Googleでは、常に新しい製品や技術を実験しており、短期間でフィードバックと提案を集めるために社員にテストを依頼している。われわれは、これをドッグフーディング(&#8220;eating your own dogfood&#8221;から)と呼んでいる。 この「ドッグフードを食べる」経験は、お客様からのフィードバックと同じくらい重要なモノになったと感じています。 ベータ版が完成した頃から、特定のお客様にもご利用頂きました。 ドッグフードを食べ、お客様からのフィードバック経験によって、ciklone(サイクロン)はチームにとって、すばらしいソフトウェアを開発するためのプラットフォームとして十分に機能しました。 オープングルーヴでは、ciklone(サイクロン)を最大限に活用して頂き、他社の利用方法を紹介することで、みなさんのチームのソフトウェア開発を効率化とコストダウンしていく支援をさせて頂きます。 オープングルーヴでは、Wikiサイトを使って、実証済みのガイドとベストプラクティス(と考えられる)を提案していきます。]]></description>
			<content:encoded><![CDATA[<p><a title="ソフトウェアエンジニアのためのSaaS版バージョン管理/バグ管理システム(プロジェクト管理システム)" href="http://ciklone.com/usage.html">ciklone(サイクロン)</a>のリリース前に、自分たちが実際にプロジェクトで利用して、 ciklone(サイクロン)を改善してきました。
サイクロン開発プロジェクトの最後の6ヶ月間にソフトウェアのライフサイクルをくり返します。すべての機能を使いながら、「BTS/SCM/プロジェクト管理に必要なことができ、効率的か」、を試験してきました。</p>

<p>開発しながら、実際の現場で利用することで、バグがどんどん見つかったし、使いにくい点、改善すべきことがよく見えます。自分たちが作ったシステムを自分たちのプロジェクトで使う最大のメリットだと思います。</p>

<p>よくいわれる「ドッグフードを食べる」ことをやったことで、BTSやバージョン管理に必要な機能と必要ではない機能を切り分けることができ、開発の現場に必要なツールとして、 ciklone(サイクロン)がリリースできました。</p>

<p>「ドッグフードを食べる」とは、
自社で作ったソフトウェアを実際の業務で利用して、評価することです。有名なのはマイクロソフトのドッグフードです。また、Google ケータイも同様です。</p>

<p><a title="シリコンバレー101" href="http://journal.mycom.co.jp/column/svalley/346/index.html">シリコンバレー101[Googleケータイ販売で、Googleは何を変えたいのか?]</a></p>

<blockquote>Googleでは、常に新しい製品や技術を実験しており、短期間でフィードバックと提案を集めるために社員にテストを依頼している。われわれは、これをドッグフーディング(&#8220;eating your own dogfood&#8221;から)と呼んでいる。</blockquote>

<p>この「ドッグフードを食べる」経験は、お客様からのフィードバックと同じくらい重要なモノになったと感じています。
ベータ版が完成した頃から、特定のお客様にもご利用頂きました。
ドッグフードを食べ、お客様からのフィードバック経験によって、ciklone(サイクロン)はチームにとって、すばらしいソフトウェアを開発するためのプラットフォームとして十分に機能しました。</p>

<p>オープングルーヴでは、ciklone(サイクロン)を最大限に活用して頂き、他社の利用方法を紹介することで、みなさんのチームのソフトウェア開発を効率化とコストダウンしていく支援をさせて頂きます。</p>

<p>オープングルーヴでは、Wikiサイトを使って、実証済みのガイドとベストプラクティス(と考えられる)を提案していきます。</p>

<div id="attachment_631" class="wp-caption aligncenter" style="width: 234px"><a href="http://wiki.ciklone.com/"><img class="size-full wp-image-631  " title="wiki.ciklone.com - 実証済みのガイドとベストプラクティス -" src="http://labo.opengroove.com/blog/wp-content/uploads/2010/08/wiki-ciklone-banner.png" alt="Wiki.ciklone.com" width="224" height="50" /></a><p class="wp-caption-text">Wiki.ciklone.com</p></div>
]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/08/25/%e3%83%89%e3%83%83%e3%82%b0%e3%83%95%e3%83%bc%e3%83%89%e3%82%92%e9%a3%9f%e3%81%b9%e3%82%8b-bts-scm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakePHP で連結テーブルのモデルは先に宣言すること</title>
		<link>http://labo.opengroove.com/blog/2010/06/30/cakephp-%e3%81%a7%e9%80%a3%e7%b5%90%e3%83%86%e3%83%bc%e3%83%96%e3%83%ab%e3%81%ae%e3%83%a2%e3%83%87%e3%83%ab%e3%81%af%e5%85%88%e3%81%ab%e5%ae%a3%e8%a8%80%e3%81%99%e3%82%8b%e3%81%93%e3%81%a8/</link>
		<comments>http://labo.opengroove.com/blog/2010/06/30/cakephp-%e3%81%a7%e9%80%a3%e7%b5%90%e3%83%86%e3%83%bc%e3%83%96%e3%83%ab%e3%81%ae%e3%83%a2%e3%83%87%e3%83%ab%e3%81%af%e5%85%88%e3%81%ab%e5%ae%a3%e8%a8%80%e3%81%99%e3%82%8b%e3%81%93%e3%81%a8/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 03:58:36 +0000</pubDate>
		<dc:creator>sugimoto</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=621</guid>
		<description><![CDATA[sugimoto です。最近、CakePHPを使ってます。 しばらくRails を使っていたこともあり、わかりやすい所もある反面、衝撃的に違うところがあったりして試行錯誤な毎日です。 先日、連結テーブルに「並び順」カラムを持たせて、hasManyAndBelongsToなリレーションの順番をつけようとしたところ、うまく動きませんでした。 プロジェクトとユーザーを以下のようなテーブルで関連つけていました projects users projects_users このとき、「各プロジェクトの参加者ごとに並び順を設定したい」という要望があり、 projects_users に position カラムを持たせて並び順を設定することにしました。 positionカラムの更新をするために ProjectsUser という中途半端なmodel クラスを作ったところ、問題発生。 projects_controller のuses 句で ProjectsUser を設定しているにもかかわらず、ProjectsUser の関数が呼べず、controller内での $this->ProjectsUser の実体がなぜか AppModel となっていました。 AppController など、ソースを確認したところ、controller のイニシャライズ時、以下のようなロジックでした。 Projectモデルのインスタンス を作成 Projectモデルで設定されているリレーションに該当するモデルのインスタンスを作成(Userなど) リレーションテーブルを扱うのインスタンス ProjectsUserを作成 その際、デフォルト実装である AppModel のインスタンスとして作成 上記作成したインスタンスはすべてキャッシュ ProjectsUserを作成するが、すでにキャッシュされているためそれを使用 つまり、上記処理がcontroller の uses句内で宣言された順に処理されているため、ProjectsUserをロードするとき、先に処理したProjectモデルのリレーションとして作成されたProjectsUserが優先されていたわけです。 今日の格言 リレーショナルテーブルのモデルを作ったら、uses 句内では必ず先に宣言すること。 ソフトウェアエンジニアのためのバグトラッキングシステム : Ciklone ソフトウェアエンジニアのためのバグトラッキングシステム]]></description>
			<content:encoded><![CDATA[<p>
sugimoto です。最近、CakePHPを使ってます。
</p>

<p>
しばらくRails を使っていたこともあり、わかりやすい所もある反面、衝撃的に違うところがあったりして試行錯誤な毎日です。
</p>

<p>
先日、連結テーブルに「並び順」カラムを持たせて、hasManyAndBelongsToなリレーションの順番をつけようとしたところ、うまく動きませんでした。
</p>

<p></p>
プロジェクトとユーザーを以下のようなテーブルで関連つけていました


<pre>
projects
users
projects_users
</pre>

<p>
このとき、「各プロジェクトの参加者ごとに並び順を設定したい」という要望があり、 projects_users に position カラムを持たせて並び順を設定することにしました。
</p>

<p>
positionカラムの更新をするために ProjectsUser という中途半端なmodel クラスを作ったところ、問題発生。
</p>

<p>
projects_controller のuses 句で ProjectsUser を設定しているにもかかわらず、ProjectsUser の関数が呼べず、controller内での $this->ProjectsUser の実体がなぜか AppModel となっていました。
</p>

<p>
AppController など、ソースを確認したところ、controller のイニシャライズ時、以下のようなロジックでした。
</p>

<ol>
  <li>Projectモデルのインスタンス を作成</li>
  <li>Projectモデルで設定されているリレーションに該当するモデルのインスタンスを作成(Userなど)</li>
  <li>リレーションテーブルを扱うのインスタンス ProjectsUserを作成</li>
  <li>その際、デフォルト実装である AppModel のインスタンスとして作成</li>
  <li>上記作成したインスタンスはすべてキャッシュ</li>
  <li>ProjectsUserを作成するが、すでにキャッシュされているためそれを使用</li>
</ol>

<p>
つまり、上記処理がcontroller の uses句内で宣言された順に処理されているため、ProjectsUserをロードするとき、先に処理したProjectモデルのリレーションとして作成されたProjectsUserが優先されていたわけです。
</p>

<h4>今日の格言</h4>

<p>
リレーショナルテーブルのモデルを作ったら、uses 句内では必ず先に宣言すること。
</p>

<h3><span style="color: #999999;">ソフトウェアエンジニアのためのバグトラッキングシステム : Ciklone</span></h3>

<p><a title="ソフトウェアエンジニアのためのバグトラッキングシステム" href="http://ciklone.com/"><img class="alignnone" title="ソフトウェアエンジニアのためのバグトラッキングシステム" src="http://www.opengroove.com/images/ciklone-banner.png" alt="ソフトウェアエンジニアのためのバグトラッキングシステム" width="224" height="50" /></a></p>

<p><a style="color: #999999;" href="http://ciklone.com/" title="ソフトウェアエンジニアのためのバグトラッキングシステム">ソフトウェアエンジニアのためのバグトラッキングシステム</a></p>
]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/06/30/cakephp-%e3%81%a7%e9%80%a3%e7%b5%90%e3%83%86%e3%83%bc%e3%83%96%e3%83%ab%e3%81%ae%e3%83%a2%e3%83%87%e3%83%ab%e3%81%af%e5%85%88%e3%81%ab%e5%ae%a3%e8%a8%80%e3%81%99%e3%82%8b%e3%81%93%e3%81%a8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ActiveRecord の conditions を作成するためのクラスを作ってみた</title>
		<link>http://labo.opengroove.com/blog/2010/06/28/activerecord-%e3%81%ae-conditions-%e3%82%92%e4%bd%9c%e6%88%90%e3%81%99%e3%82%8b%e3%81%9f%e3%82%81%e3%81%ae%e3%82%af%e3%83%a9%e3%82%b9%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%81%9f/</link>
		<comments>http://labo.opengroove.com/blog/2010/06/28/activerecord-%e3%81%ae-conditions-%e3%82%92%e4%bd%9c%e6%88%90%e3%81%99%e3%82%8b%e3%81%9f%e3%82%81%e3%81%ae%e3%82%af%e3%83%a9%e3%82%b9%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%81%9f/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 03:41:22 +0000</pubDate>
		<dc:creator>morimoto</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=611</guid>
		<description><![CDATA[どうもお久しぶりです。 morimotoです。 今日は複雑なActiveRecordの条件句を作成する際に（もしかしたら）楽になるのではないかと思いconditionを生成するクラスを作ってみました。 class ARCond module OPERATION EQUAL = '=' NOT_EQUAL = '' IN = 'IN' GREATER = '>' GREATER_OR_EQUAL = '>=' LESS = '< ' LESS_OR_EQUAL = ']]></description>
			<content:encoded><![CDATA[<p>どうもお久しぶりです。</p>

<p>morimotoです。</p>

<p>今日は複雑なActiveRecordの条件句を作成する際に（もしかしたら）楽になるのではないかと思いconditionを生成するクラスを作ってみました。</p>

<pre>
  class ARCond
    module OPERATION
      EQUAL            = '='
      NOT_EQUAL        = '<>'
      IN               = 'IN'
      GREATER          = '>'
      GREATER_OR_EQUAL = '>='
      LESS             = '< '
      LESS_OR_EQUAL    = '<='
    end

    attr_reader :conditions, :parameters, :separator, :table_name

    def initialize(separator="AND", table_name=nil)
      @conditions = []
      @parameters = []
      @separator  = separator
      @table_name = table_name
    end

    # column = ?
    def equal(column, value, table=nil)
      add(column, value, OPERATION::EQUAL, table)
    end
    # column <> ?
    def not_equal(column, value, table=nil)
      add(column, value, OPERATION::NOT_EQUAL, table)
    end
    # column IN (?,?,?...)
    def in(column, value, table=nil)
      add(column, value, OPERATION::IN, table)
    end
    # column > ?
    def greater(column, value, table=nil)
      add(column, value, OPERATION::GREATER, table)
    end
    # column >= ?
    def greater_or_equal(column, value, table=nil)
      add(column, value, OPERATION::GREATER_OR_EQUAL, table)
    end
    # column < ?
    def less(column, value, table=nil)
      add(column, value, OPERATION::LESS, table)
    end
    # column <= ?
    def less_or_equal(column, value, table=nil)
      add(column, value, OPERATION::LESS_OR_EQUAL, table)
    end

    def << (other)
      cond = nil
      param = []
      if other.kind_of? ARCond
        c = other.build
        cond = c.delete_at(0)
        param = c
      elsif other.kind_of? String
        cond = other
      elsif other.kind_of? Array
        cond = other.delete_at(0)
        param = other
      end
      unless cond.blank?
        @conditions << cond
        @parameters.concat(param)
      end
      return self.build
    end

    # [conditions, param, param, param,...]
    def build
      [join_conditions].concat(@parameters)
    end

    private
    def join_conditions
      sep = " #{@separator} "
      "(#{@conditions.join(sep)})"
    end

    def column_fullname(column, table=nil)
      unless column =~ /^[\w]+\.[\w]+$/
        if table_name = table.blank? ? @table_name : table
          return "#{table_name}.#{column}"
        end
      end
      column
    end

    def add(column, value, operation, table=nil)
      parts = [column_fullname(column, table), operation]
      param = [value].flatten
      parts << ((operation == OPERATION::IN) ? "(#{param.map{'?'}.join(',')})" : "?")
      self << [parts.join(' ')].concat(param)
    end
  end
</pre>

<p>使い方の例）</p>

</pre><pre>
# 基本スタイル
c1 = ARCond.new("AND")
c1.equal("col1", true)
  # => ["(col1 = ?)", true]
c1.not_equal("col2", nil)
  # => ["(col1 = ? AND col2 <> ?)", true, nil]
c1.in("col3", [31,32,33])
  # => ["(col1 = ? AND col2 <> ? AND col3 IN (?,?,?))", true, nil, 31, 32, 33]



# 連結文字を変更する
c2 = ARCond.new("OR")

# 指定した連結文字で結合されていく
c2.greater("col4", 100)
  # => ["(col4 > ?)", 100]
c2.less("col4", 200)
  # => ["(col4 > ? OR col4 < ?)", 100, 200]

# 配列みたいに追加していく
c1 << c2
  # => ["(col1 = ? AND col2 <> ? AND col3 IN (?,?,?) AND (col4 > ? OR col4 < ?))", true, nil, 31, 32, 33, 100, 200]



# 引数なしはANDで連結
c3 = ARCond.new()

# いつもどおりの配列の conditions もくっつけれる
c3 << ["col5 = ? AND col6 IN (?,?)", 11,22,33]
  # => ["(col5 = ? AND col6 IN (?,?))", 11, 22, 33]

# 任意文字列もくっつけれる
c3 < < "col7 > col8"
  # => ["(col5 = ? AND col6 IN (?,?) AND col7 > col8)", 11, 22, 33]


# テーブル名を指定する
c4 = ARCond.new("OR", "sample")

# カラム名の頭にテーブル名が付与される
c4.greater_or_equal("col9", 300)
  # => ["(sample.col9 >= ?)", 300]
c4.less_or_equal("col9", 400)
  # => ["(sample.col9 >= ? OR sample.col9 < = ?)", 300, 400]

# くっつけるときにテーブル名を指定する
c4.equal("col10", false, "banana")
  # => ["(sample.col9 >= ? OR sample.col9 < = ? OR banana.col10 = ?)", 300, 400, false]

c3 << c4
  # => ["(col5 = ? AND col6 IN (?,?) AND col7 > col8 AND (sample.col9 >= ? OR sample.col9 < = ? OR banana.col10 = ?))", 11, 22, 33, 300, 400, false]

c1 << c3
  # => ["(col1 = ? AND col2 <> ? AND col3 IN (?,?,?) AND (col4 > ? OR col4 < ?) AND (col5 = ? AND col6 IN (?,?) AND col7 > col8 AND (sample.col9 >= ? OR sample.col9 < = ? OR banana.col10 = ?)))", true, nil, 31, 32, 33, 100, 200, 11, 22, 33, 300, 400, false]


# 最終的に使いたいタイミングで build してあげたらよい
c1.build
  # => ["(col1 = ? AND col2 <> ? AND col3 IN (?,?,?) AND (col4 > ? OR col4 < ?) AND (col5 = ? AND col6 IN (?,?) AND col7 > col8 AND (sample.col9 >= ? OR sample.col9 < = ? OR banana.col10 = ?)))", true, nil, 31, 32, 33, 100, 200, 11, 22, 33, 300, 400, false]

</pre>

<p>作っておいてなんですが、テーブルが複数あったり、集計クエリが絡んできたりと、複雑になればなるほど自分でwhere句を書いたほうが早い気がします。</p>

<p>以上、morimoto でした。</p>
</pre>]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/06/28/activerecord-%e3%81%ae-conditions-%e3%82%92%e4%bd%9c%e6%88%90%e3%81%99%e3%82%8b%e3%81%9f%e3%82%81%e3%81%ae%e3%82%af%e3%83%a9%e3%82%b9%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%81%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>オープンソースソフトウェアの育て方</title>
		<link>http://labo.opengroove.com/blog/2010/05/24/%e3%82%aa%e3%83%bc%e3%83%97%e3%83%b3%e3%82%bd%e3%83%bc%e3%82%b9%e3%82%bd%e3%83%95%e3%83%88%e3%82%a6%e3%82%a7%e3%82%a2%e3%81%ae%e8%82%b2%e3%81%a6%e6%96%b9/</link>
		<comments>http://labo.opengroove.com/blog/2010/05/24/%e3%82%aa%e3%83%bc%e3%83%97%e3%83%b3%e3%82%bd%e3%83%bc%e3%82%b9%e3%82%bd%e3%83%95%e3%83%88%e3%82%a6%e3%82%a7%e3%82%a2%e3%81%ae%e8%82%b2%e3%81%a6%e6%96%b9/#comments</comments>
		<pubDate>Mon, 24 May 2010 04:49:34 +0000</pubDate>
		<dc:creator>syoji</dc:creator>
				<category><![CDATA[ソフトウェア開発]]></category>
		<category><![CDATA[読書]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=568</guid>
		<description><![CDATA[プロジェクトが失敗に終わる可能性は非常に高く、 おそらく90–95%くらい 「オープンソースソフトウェアの育て方」という書籍があります。副題にフリーソフトウェアプロジェクトを成功させるコツとあるように、著者がオープンソースプロジェクトでの経験を元に実例を交えて説明されています。バージョン管理システムで有名なSubversionプロジェクトでの実際の経験から書かれています。 実践的な内容なので、ぜひソフトウェアエンジニアの方には読んで欲しい内容です。 （技術的な側面よりもオープンソースプロジェクトをうまく運営するための考え方やプロジェクト運営方法についての説明が多くなっています。） さらに、うれしいことにウェブで全文を公開しているためだれでも読むことが出来ます（当然、日本語で）300ページにもなる専門的でためになる文書を公開された作者の方と翻訳者の方に感謝しなければいけません。 本の内容で特にビジネスアプリケーション開発の困難な点と共通する部分が多く（同じソフト開発なので当たり前ですが）さらに多くの課題に対処するための方法も参考になります。 「3. 技術的な問題」で紹介されているツールとその運用方法は、ビジネスアプリケーションの現場でも十分有効に使えるので、新入社員などに読ませるのも良いと思います。紹介されているツール群は若干古いですが、どのようなツールを、どのような場面で、どのように使っているのかを知る上でとても分かりやすいです。 また、「6.コミュニケーション」などは自分たちの開発でも学ぶべきコトが多いと思った部分で、読んでおくべき章だと思います。 書いたことがすべて 陥りがちな罠 付録C.なんで自転車置場の色まで気にしなきゃならないの？ ソフトウェアエンジニアに求められる能力として、はじめに思いついたことは、「文章を作成する力」です。コミュニケーション能力や提案力、プログラミング能力などよく言われる能力も必要であると思いますが、自分の考えを正確に正しく伝えるための書く力はインターネットが仕事に欠かせないツールになったことで重要であると考えています。 そのためには書く（まとめる）内容以前に考える力が重要になってきますが。。。 http://subversion.tigris.org/]]></description>
			<content:encoded><![CDATA[<div style="float:right;"><a href="http://www.amazon.co.jp/%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E8%82%B2%E3%81%A6%E6%96%B9-Karl-Fogel/dp/4873114128"><img class="alignright size-full wp-image-599" title="オープンソースソフトウェアの育て方" src="http://labo.opengroove.com/blog/wp-content/uploads/2010/05/20100507.jpg" alt="オープンソースソフトウェアの育て方" width="210" height="210" /></a></div>

<blockquote>プロジェクトが失敗に終わる可能性は非常に高く、 おそらく90–95%くらい</blockquote>

<p>「オープンソースソフトウェアの育て方」という書籍があります。副題にフリーソフトウェアプロジェクトを成功させるコツとあるように、著者がオープンソースプロジェクトでの経験を元に実例を交えて説明されています。バージョン管理システムで有名な<a href="http://subversion.tigris.org/">Subversionプロジェクト</a>での実際の経験から書かれています。
実践的な内容なので、ぜひソフトウェアエンジニアの方には読んで欲しい内容です。
（技術的な側面よりもオープンソースプロジェクトをうまく運営するための考え方やプロジェクト運営方法についての説明が多くなっています。）</p>

<p>さらに、うれしいことにウェブで<a href="http://producingoss.com/ja/index.html">全文を公開</a>しているためだれでも読むことが出来ます（当然、日本語で）300ページにもなる専門的でためになる文書を公開された作者の方と翻訳者の方に感謝しなければいけません。</p>

<p>本の内容で特にビジネスアプリケーション開発の困難な点と共通する部分が多く（同じソフト開発なので当たり前ですが）さらに多くの課題に対処するための方法も参考になります。
「<a href="http://producingoss.com/ja/technical-infrastructure.html">3. 技術的な問題</a>」で紹介されているツールとその運用方法は、ビジネスアプリケーションの現場でも十分有効に使えるので、新入社員などに読ませるのも良いと思います。紹介されているツール群は若干古いですが、どのようなツールを、どのような場面で、どのように使っているのかを知る上でとても分かりやすいです。</p>

<p>また、「<a href="http://producingoss.com/ja/communications.html">6.コミュニケーション</a>」などは自分たちの開発でも学ぶべきコトが多いと思った部分で、読んでおくべき章だと思います。</p>

<ul>
    <li><span class="sect1"> </span><a href="http://producingoss.com/ja/communications.html#you-are-what-you-write">書いたことがすべて</a></li>
    <li><a href="http://producingoss.com/ja/common-pitfalls.html">陥りがちな罠</a></li>
    <li><a href="http://producingoss.com/ja/bikeshed-full.html">付録C.なんで自転車置場の色まで気にしなきゃならないの？</a></li>
</ul>

<p>ソフトウェアエンジニアに求められる能力として、はじめに思いついたことは、「文章を作成する力」です。コミュニケーション能力や提案力、プログラミング能力などよく言われる能力も必要であると思いますが、自分の考えを正確に正しく伝えるための書く力はインターネットが仕事に欠かせないツールになったことで重要であると考えています。</p>

<p>そのためには書く（まとめる）内容以前に考える力が重要になってきますが。。。</p>

<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">http://subversion.tigris.org/</div>
]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/05/24/%e3%82%aa%e3%83%bc%e3%83%97%e3%83%b3%e3%82%bd%e3%83%bc%e3%82%b9%e3%82%bd%e3%83%95%e3%83%88%e3%82%a6%e3%82%a7%e3%82%a2%e3%81%ae%e8%82%b2%e3%81%a6%e6%96%b9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>どこでもサーバー管理ができる iPhoneアプリ 「TouchTerm」</title>
		<link>http://labo.opengroove.com/blog/2010/05/06/%e3%81%a9%e3%81%93%e3%81%a7%e3%82%82%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e7%ae%a1%e7%90%86%e3%81%8c%e3%81%a7%e3%81%8d%e3%82%8b-iphone%e3%82%a2%e3%83%97%e3%83%aa-%e3%80%8ctouchterm%e3%80%8d/</link>
		<comments>http://labo.opengroove.com/blog/2010/05/06/%e3%81%a9%e3%81%93%e3%81%a7%e3%82%82%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e7%ae%a1%e7%90%86%e3%81%8c%e3%81%a7%e3%81%8d%e3%82%8b-iphone%e3%82%a2%e3%83%97%e3%83%aa-%e3%80%8ctouchterm%e3%80%8d/#comments</comments>
		<pubDate>Thu, 06 May 2010 06:35:51 +0000</pubDate>
		<dc:creator>sugimoto</dc:creator>
				<category><![CDATA[ZABBIX]]></category>
		<category><![CDATA[ツール]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Terminal]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=558</guid>
		<description><![CDATA[sugimotoです。 Webサービスの運用ではサーバーやサービスの監視が欠かせないと思います。 オープングルーヴでも突然のサーバー停止や、サービス停止、定期処理の失敗などに備え、監視システムを使って障害発生時にはメール通知するようにしています。 GW中に出かける途中で、監視システムとして運用しているZABBIXから警告メールが飛んできました。 パソコンを持たずに出かけていて、長距離バスに乗っていたんですが、iPhoneにインストールしていたTouchTermを使いました。 TouchTermはiPhoneアプリとして動作するSSHターミナルです。 アプリケーション内で作成したSSHキーのパブリックキーをあらかじめサーバーにおいておくことで、サーバーにSSH経由でログインすることができます。 iPhoneの画面とキーでも十分にサーバー上のログや状況の確認が可能で、問題の箇所をすぐに特定、対応することができました。 iPhoneの画面とキーを使っての操作のため、長時間操作や大きな設定変更は難しいですが、緊急時の一時的な対応には十分使えるツールです。 ソフトウェアエンジニアのためのバグトラッキングシステム : Ciklone ソフトウェアエンジニアのためのバグトラッキングシステム]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jbrink.net/touchterm/"><img src="http://labo.opengroove.com/blog/wp-content/uploads/2010/05/tt_graphic.gif" alt="tt_graphic" title="tt_graphic" width="196" height="193" class="alignright size-full wp-image-560" style="float: right;" /></a></p>

<p>sugimotoです。</p>

<p>
Webサービスの運用ではサーバーやサービスの監視が欠かせないと思います。
オープングルーヴでも突然のサーバー停止や、サービス停止、定期処理の失敗などに備え、監視システムを使って障害発生時にはメール通知するようにしています。
</p>

<p>
GW中に出かける途中で、監視システムとして運用しているZABBIXから警告メールが飛んできました。
</p>

<p>
パソコンを持たずに出かけていて、長距離バスに乗っていたんですが、iPhoneにインストールしていた<a href="http://www.jbrink.net/touchterm/">TouchTerm</a>を使いました。
</p>

<p>
TouchTermはiPhoneアプリとして動作するSSHターミナルです。
アプリケーション内で作成したSSHキーのパブリックキーをあらかじめサーバーにおいておくことで、サーバーにSSH経由でログインすることができます。
</p>

<p>
iPhoneの画面とキーでも十分にサーバー上のログや状況の確認が可能で、問題の箇所をすぐに特定、対応することができました。
</p>

<p>
iPhoneの画面とキーを使っての操作のため、長時間操作や大きな設定変更は難しいですが、緊急時の一時的な対応には十分使えるツールです。
</p>

<h3><span style="color: #999999;">ソフトウェアエンジニアのためのバグトラッキングシステム : Ciklone</span></h3>

<p><a title="ソフトウェアエンジニアのためのバグトラッキングシステム" href="http://ciklone.com/"><img class="alignnone" title="ソフトウェアエンジニアのためのバグトラッキングシステム" src="http://www.opengroove.com/images/ciklone-banner.png" alt="ソフトウェアエンジニアのためのバグトラッキングシステム" width="224" height="50" /></a></p>

<p><a style="color: #999999;" href="http://ciklone.com/" title="ソフトウェアエンジニアのためのバグトラッキングシステム">ソフトウェアエンジニアのためのバグトラッキングシステム</a></p>
]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/05/06/%e3%81%a9%e3%81%93%e3%81%a7%e3%82%82%e3%82%b5%e3%83%bc%e3%83%90%e3%83%bc%e7%ae%a1%e7%90%86%e3%81%8c%e3%81%a7%e3%81%8d%e3%82%8b-iphone%e3%82%a2%e3%83%97%e3%83%aa-%e3%80%8ctouchterm%e3%80%8d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ツールを使った情報共有#1（仕事で Wiki を使いたい）</title>
		<link>http://labo.opengroove.com/blog/2010/03/16/%e3%83%84%e3%83%bc%e3%83%ab%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e6%83%85%e5%a0%b1%e5%85%b1%e6%9c%891%ef%bc%88%e4%bb%95%e4%ba%8b%e3%81%a7-wiki-%e3%82%92%e4%bd%bf%e3%81%84%e3%81%9f%e3%81%84%ef%bc%89/</link>
		<comments>http://labo.opengroove.com/blog/2010/03/16/%e3%83%84%e3%83%bc%e3%83%ab%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e6%83%85%e5%a0%b1%e5%85%b1%e6%9c%891%ef%bc%88%e4%bb%95%e4%ba%8b%e3%81%a7-wiki-%e3%82%92%e4%bd%bf%e3%81%84%e3%81%9f%e3%81%84%ef%bc%89/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 05:44:46 +0000</pubDate>
		<dc:creator>syoji</dc:creator>
				<category><![CDATA[Wiki]]></category>
		<category><![CDATA[プロジェクト管理]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=530</guid>
		<description><![CDATA[社内での仕事術 #1 社内での仕事術について紹介したいと思います。 ソフトウェア開発は一つ一つの案件をプロジェクトとしてすすめるため、はじめにプロジェクトチームを作ります。 プロジェクトチームは提案内容や得意分野により主担当がかわります。 プロジェクトでは複数のメンバーが集まって仕事をすることになるため、情報共有はとても重要。 オープングルーヴではどのようにしているのか、ツールを使った情報共有#1として「Wikiを仕事で使う」について書きたいと思います。 Wikiとは「ウィキ」と言いますが、ウェブブラウザを使ってページの作成・編集ができるコンテンツサービスです。一人でメモ書きとして利用している方もいると思いますが、けっこう書込のためにページを開く。という動作が面倒になりがちということはあると思います。 弊社で利用する場合は、複数のメンバーでプロジェクトを進める上でガリガリ書き込みます。これはあるルールを決めているためですが、そのルールのおかげでWikiがなくてはならいツールになっています。 ルール : プロジェクトの成果物(中間成果物)はWikiで一元管理 Wikiのメリット 会議をしながら議事録(画面を見ながらみんなで確認) 顧客向けの議事録 顧客との打合せで出来る議事録はWikiをPDF化やメールで共有 設計書(技術メモ、検討メモ)、技術方式に対する他チームのコメント 開発環境構築メモなど、開発に関わる情報源 世代管理機能、ページ単位で履歴を確認し、追加された・削除されたがカラー表示される(下図) などなど、メールでも同様のことはできますが、プロジェクトのポータルとして利用でき、大切な文書が埋もれない･･･(メールは探すのが大変) プロジェクトメンバーで使うことで、ガリガリ更新され、すぐにWikiが必須の情報共有ツールになりました。 デメリットは&#8230; しかし、良い面ばかりではないです。新しく加わったメンバーなどにとっては使ったことがないツールのため、慣れるまで大変かも知れません。 「Wikiを知らない人や初めて使う人にとって慣れ親しんだインターフェースではない。」ということです。ファイル名がない、特殊なフォーマット･･･ Wikiを仕事で使いたい人へ セキュアで、1プロジェクト無料のcikloneを評価してください。]]></description>
			<content:encoded><![CDATA[<h2>社内での仕事術 #1</h2>

<p>社内での仕事術について紹介したいと思います。
ソフトウェア開発は一つ一つの案件をプロジェクトとしてすすめるため、はじめにプロジェクトチームを作ります。</p>

<p>プロジェクトチームは提案内容や得意分野により主担当がかわります。
プロジェクトでは複数のメンバーが集まって仕事をすることになるため、情報共有はとても重要。</p>

<p><a href="http://www.opengroove.com/">オープングルーヴ</a>ではどのようにしているのか、ツールを使った情報共有#1として「Wikiを仕事で使う」について書きたいと思います。</p>

<p>Wikiとは「ウィキ」と言いますが、ウェブブラウザを使ってページの作成・編集ができるコンテンツサービスです。一人でメモ書きとして利用している方もいると思いますが、けっこう書込のためにページを開く。という動作が面倒になりがちということはあると思います。</p>

<p>弊社で利用する場合は、複数のメンバーでプロジェクトを進める上でガリガリ書き込みます。これはあるルールを決めているためですが、そのルールのおかげでWikiがなくてはならいツールになっています。</p>

<blockquote>ルール : プロジェクトの成果物(中間成果物)はWikiで一元管理</blockquote>

<h2>Wikiのメリット</h2>

<ul>
    <li> 会議をしながら議事録(画面を見ながらみんなで確認)</li>
    <li> 顧客向けの議事録</li>
    <li> 顧客との打合せで出来る議事録はWikiをPDF化やメールで共有</li>
    <li> 設計書(技術メモ、検討メモ)、技術方式に対する他チームのコメント</li>
    <li> 開発環境構築メモなど、開発に関わる情報源</li>
    <li> 世代管理機能、ページ単位で履歴を確認し、追加された・削除されたがカラー表示される(下図)</li>
</ul>

<div id="attachment_549" class="wp-caption aligncenter" style="width: 570px"><a href="http://labo.opengroove.com/blog/wp-content/uploads/2010/03/labo_blog_ciklone_wiki11.jpg"><img class="size-full wp-image-549 " title="Wikiによる備忘録・ルール" src="http://labo.opengroove.com/blog/wp-content/uploads/2010/03/labo_blog_ciklone_wiki11.jpg" alt="Wikiによる備忘録・ルール" width="560" height="329" /></a><p class="wp-caption-text">Wikiによる備忘録・ルール</p></div>

<div id="attachment_550" class="wp-caption aligncenter" style="width: 570px"><a href="http://labo.opengroove.com/blog/wp-content/uploads/2010/03/labo_blog_ciklone_wiki2.jpg"><img class="size-full wp-image-550 " title="Wikiの世代管理(履歴)" src="http://labo.opengroove.com/blog/wp-content/uploads/2010/03/labo_blog_ciklone_wiki2.jpg" alt="Wikiの世代管理(履歴)" width="560" height="329" /></a><p class="wp-caption-text">Wikiの世代管理(履歴)</p></div>

<p style="text-align: center;"></p>

<p>などなど、メールでも同様のことはできますが、プロジェクトのポータルとして利用でき、大切な文書が埋もれない･･･(メールは探すのが大変)
プロジェクトメンバーで使うことで、ガリガリ更新され、すぐにWikiが必須の情報共有ツールになりました。</p>

<h3>デメリットは&#8230;</h3>

<p>しかし、良い面ばかりではないです。新しく加わったメンバーなどにとっては使ったことがないツールのため、慣れるまで大変かも知れません。
「Wikiを知らない人や初めて使う人にとって慣れ親しんだインターフェースではない。」ということです。ファイル名がない、特殊なフォーマット･･･</p>

<blockquote>Wikiを仕事で使いたい人へ
セキュアで、1プロジェクト無料の<a href="http://ciklone.com/usage.html">ciklone</a>を評価してください。</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/03/16/%e3%83%84%e3%83%bc%e3%83%ab%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e6%83%85%e5%a0%b1%e5%85%b1%e6%9c%891%ef%bc%88%e4%bb%95%e4%ba%8b%e3%81%a7-wiki-%e3%82%92%e4%bd%bf%e3%81%84%e3%81%9f%e3%81%84%ef%bc%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IIS マネージャから FastCGI の設定を行う</title>
		<link>http://labo.opengroove.com/blog/2010/02/22/fastcgi-settings-with-iis-manager/</link>
		<comments>http://labo.opengroove.com/blog/2010/02/22/fastcgi-settings-with-iis-manager/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 04:21:17 +0000</pubDate>
		<dc:creator>omae</dc:creator>
				<category><![CDATA[FastCGI]]></category>
		<category><![CDATA[IIS]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=520</guid>
		<description><![CDATA[こんにちわ。omae です。 さて、前回では IIS7 + FastCGI で PHP 5.3 を実行できるようにしました。 少し試しているうちに php のプロセス自体は 4 つまで増えるようになっている…ということに気づきました。 また当然ながらこの設定を変更する方法が用意されており、一つは %WINDIR%\system32\inetsrv\appcmd コマンドを用いるもので、もう一つは IIS マネージャから行うものです。 ここでは IIS マネージャから行う方法をやってみます。 手順 1. IIS 7.0 Administration Pack をインストール Administration Pack : The Official Microsoft IIS Site からインストーラをダウンロードします。右のほうに Or, download x86 / x64 のような表記があるので実行環境に合ったものをダウンロードします。 ダウンロードしたらその MSI を実行してインストールします。 2. IIS マネージャを起動 IIS マネージャを起動すると FastCGI Settings [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちわ。omae です。</p>

<p>さて、前回では <a href="/blog/2010/02/22/php-5-3-on-iis7-via-fastcgi/">IIS7 + FastCGI で PHP 5.3 を実行できる</a>ようにしました。</p>

<p>少し試しているうちに php のプロセス自体は 4 つまで増えるようになっている…ということに気づきました。
また当然ながらこの設定を変更する方法が用意されており、一つは <code>%WINDIR%\system32\inetsrv\appcmd</code> コマンドを用いるもので、もう一つは IIS マネージャから行うものです。</p>

<p>ここでは IIS マネージャから行う方法をやってみます。</p>

<h2>手順</h2>

<h3>1. IIS 7.0 Administration Pack をインストール</h3>

<p><a href="http://www.iis.net/expand/AdministrationPack">Administration Pack : The Official Microsoft IIS Site</a> からインストーラをダウンロードします。右のほうに <code>Or, download x86 / x64</code> のような表記があるので実行環境に合ったものをダウンロードします。</p>

<p>ダウンロードしたらその MSI を実行してインストールします。</p>

<h3>2. IIS マネージャを起動</h3>

<p>
IIS マネージャを起動すると FastCGI Settings アイコンが増えているのが確認出来ると思います。<br />
<img src="/blog/wp-content/uploads/2010/02/iis7-fastcgi-settings.png" />
</p>

<h3>3. FastCGI Settings を開く</h3>

<p>FastCGI Settings アイコンを開くと設定されている FastCGI アプリケーションの一覧が表示されます。
一覧から設定したいアプリケーションのところで double click すると設定が変更出来るようになっています。<br />
<img src="/blog/wp-content/uploads/2010/02/iis7-fastcgi-settings-2.png" />
</p>

<p>主に変更するのは MaxInstances (FastCGI ワーカープロセスの数) と InstanceMaxRequests (各ワーカープロセスの最大のリクエスト処理数。この値に到達するまでプロセスが再利用される) だと思います。</p>

<p>それ以外の設定の詳細は <a href="http://technet.microsoft.com/ja-jp/library/ee431554.aspx">IIS 7.0 コンフィギュレーション リファレンス &#8211; FastCGI アプリケーション &lt;application&gt;</a> に解説がありますので、これを確認しつつ必要であれば設定を行います。</p>

<h2>参考</h2>

<ul>
<li><a href="http://learn.iis.net/page.aspx/246/using-fastcgi-to-host-php-applications-on-iis-70/">Using FastCGI to Host PHP Applications on IIS 7.0 : Host Applications on the Microsoft Web Platform : Running PHP Applications on IIS : The Official Microsoft IIS Site</a></li>
</ul>

<h3><span style="color: #999999;">ソフトウェアエンジニアのためのバグトラッキングシステム : Ciklone</span></h3>

<p><a title="ソフトウェアエンジニアのためのバグトラッキングシステム" href="http://ciklone.com/"><img class="alignnone" title="ソフトウェアエンジニアのためのバグトラッキングシステム" src="http://www.opengroove.com/images/ciklone-banner.png" alt="ソフトウェアエンジニアのためのバグトラッキングシステム" width="224" height="50" /></a></p>

<p><a style="color: #999999;" href="http://ciklone.com/" title="ソフトウェアエンジニアのためのバグトラッキングシステム">ソフトウェアエンジニアのためのバグトラッキングシステム</a></p>
]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/02/22/fastcgi-settings-with-iis-manager/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IIS 7 + FastCGI で PHP 5.3 を実行する</title>
		<link>http://labo.opengroove.com/blog/2010/02/22/php-5-3-on-iis7-via-fastcgi/</link>
		<comments>http://labo.opengroove.com/blog/2010/02/22/php-5-3-on-iis7-via-fastcgi/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 03:05:30 +0000</pubDate>
		<dc:creator>omae</dc:creator>
				<category><![CDATA[FastCGI]]></category>
		<category><![CDATA[IIS]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labo.opengroove.com/blog/?p=493</guid>
		<description><![CDATA[こんにちわ。omae です。 今回は IIS 7 で PHP 5.3 を実行する環境が必要になったのでその手順を残しておきたいと思います。 作業しようとしてから気づいたのですが PHP 5.3 から isapi モジュールが廃止されていました。PHP 5.2 以前までは isapi モジュールで環境を作成していたのですが、廃止されてしまったものはしょうがありません。IIS 7 からは FastCGI が正式に対応しているので、こちらで設定することにします。 手順 1. PHP 5.3.1 をインストール PHP For Windows: Binaries and sources Releases より今回は VC6 x86 Thread Safe (ZIP) を使うことにしました。この zip ファイルを C:\php に展開します。 ここでコマンドプロンプトを起動して C:\php\php-cgi.exe -h が実行できることを確認しておきます。実行すると以下のようなエラーが上がる場合は php.ini から extension=php_mssql.dll をコメントアウトします。SQL Server [...]]]></description>
			<content:encoded><![CDATA[<p>こんにちわ。omae です。</p>

<p>今回は IIS 7 で PHP 5.3 を実行する環境が必要になったのでその手順を残しておきたいと思います。</p>

<p>作業しようとしてから気づいたのですが PHP 5.3 から isapi モジュールが廃止されていました。PHP 5.2 以前までは isapi モジュールで環境を作成していたのですが、廃止されてしまったものはしょうがありません。IIS 7 からは FastCGI が正式に対応しているので、こちらで設定することにします。</p>

<h2>手順</h2>

<h3>1. PHP 5.3.1 をインストール</h3>

<p><a href="http://windows.php.net/download/">PHP For Windows: Binaries and sources Releases</a> より今回は <a href="http://windows.php.net/downloads/releases/php-5.3.1-Win32-VC6-x86.zip">VC6 x86 Thread Safe (ZIP)</a> を使うことにしました。この zip ファイルを C:\php に展開します。</p>

<p>ここでコマンドプロンプトを起動して <code>C:\php\php-cgi.exe -h</code> が実行できることを確認しておきます。実行すると以下のようなエラーが上がる場合は php.ini から <code>extension=php_mssql.dll</code> をコメントアウトします。SQL Server に接続する予定があるなら ntwdblib.dll を準備します。</p>

<p><img src="/blog/wp-content/uploads/2010/02/iis7-php-ntwdblib.png" /></p>

<p>無事に実行出来た場合:
<pre>C:\&gt;C:\php\php-cgi.exe -h
Usage: php [-q] [-h] [-s] [-v] [-i] [-f &lt;file&gt;]
       php &lt;file&gt; [args...]
  -a               Run interactively
  -b &lt;address:port&gt;|&lt;port&gt; Bind Path for external FASTCGI Server mode
  -C               Do not chdir to the script's directory
  -c &lt;path&gt;|&lt;file&gt; Look for php.ini file in this directory
  -n               No php.ini file will be used
  -d foo[=bar]     Define INI entry foo with value 'bar'
  -e               Generate extended information for debugger/profiler
  -f &lt;file&gt;        Parse &lt;file&gt;.  Implies `-q'
  -h               This help
  -i               PHP information
  -l               Syntax check only (lint)
  -m               Show compiled in modules
  -q               Quiet-mode.  Suppress HTTP Header output.
  -s               Display colour syntax highlighted source.
  -v               Version number
  -w               Display source with stripped comments and whitespace.
  -z &lt;file&gt;        Load Zend extension &lt;file&gt;.
  -T &lt;count&gt;       Measure execution time of script repeated &lt;count&gt; times.
</pre></p>

<h3>2. IIS で FastCGI が使えるように設定します</h3>

<p>サーバーマネージャを起動して「Web サーバー (IIS)」の機能に「CGI」がインストール済みになっていることを確認します。
インストールされていない場合は「役割サービスの追加」からインストールします。</p>

<p><img src="/blog/wp-content/uploads/2010/02/iis7-cgi.png" /></p>

<h3>3. php.ini に fastcgi のための設定を行う</h3>

<p>php.ini を開いて次の設定に変更します。
<pre>fastcgi.impersonate = 1
fastcgi.logging = 0
cgi.fix_pathinfo = 1
cgi.force_redirect = 0</pre>
</p>

<h3>4. IIS マネージャから PHP のハンドラを設定する</h3>

<p>
a. IIS マネージャを起動し、ハンドラマッピングを開きます。<br />
<img src="/blog/wp-content/uploads/2010/02/iis7-handler-mapping.png" />
</p>

<p>
b. 「モジュールハンドラの追加」を選択し、以下の要領で *.php に対して fastcgi による php の実行を設定します。<br />
<img src="/blog/wp-content/uploads/2010/02/iis7-add-php-handler.png" />
</p>

<h3>5. phpinfo.php にアクセスして確認</h3>

<p>C:\inetpub\wwwroot\phpinfo.php などに <code>&lt;?php phpinfo();</code> と書いたファイルを用意して、このファイルにブラウザからアクセスしてみます。<br />
<img src="/blog/wp-content/uploads/2010/02/iis7-phpinfo.png" />
</p>

<p>無事に phpinfo() が参照できれば、設定は完了です。</p>

<p>ついでにタスクマネージャを起動して FastCGI なので php-cgi.exe プロセスがいるか確認してみましょう。<br />
<img src="/blog/wp-content/uploads/2010/02/iis7-taskmgr.png" /><br />
ちゃんといますね。
</p>

<h2>参考</h2>

<ul>
<li><a href="http://www.php.net/manual/ja/install.windows.iis7.php">PHP: Microsoft IIS 7.0 以降 &#8211; Manual</a></li>
<li><a href="http://learn.iis.net/page.aspx/246/using-fastcgi-to-host-php-applications-on-iis-70/">Using FastCGI to Host PHP Applications on IIS 7.0 : Host Applications on the Microsoft Web Platform : Running PHP Applications on IIS : The Official Microsoft IIS Site</a></li>
</ul>

<h3><span style="color: #999999;">ソフトウェアエンジニアのためのバグトラッキングシステム : Ciklone</span></h3>

<p><a title="ソフトウェアエンジニアのためのバグトラッキングシステム" href="http://ciklone.com/"><img class="alignnone" title="ソフトウェアエンジニアのためのバグトラッキングシステム" src="http://www.opengroove.com/images/ciklone-banner.png" alt="ソフトウェアエンジニアのためのバグトラッキングシステム" width="224" height="50" /></a></p>

<p><a style="color: #999999;" href="http://ciklone.com/" title="ソフトウェアエンジニアのためのバグトラッキングシステム">ソフトウェアエンジニアのためのバグトラッキングシステム</a></p>
]]></content:encoded>
			<wfw:commentRss>http://labo.opengroove.com/blog/2010/02/22/php-5-3-on-iis7-via-fastcgi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

