ビットフラグを追加する

「2つの地区で利用したい」という想定外の使い方をリクエストされて頭を抱えている。
自分の地区以外でもリストに名前を表示するってな感じが目的です。

  • モデルに数値型のotherを作る
  • 4地区をビットで表現して保存するときに10進数にする
  • 編集は強引に2進数に戻す

4地区で5ビット使っていますが、10ビットまで用意してからの変換にすれば楽だったなーとか思う。

AptanaStudioが起動しない

AptanaStudio.exe(lnkではない)を管理者として実行する(cleanオプションも付けた)

マイグレーションファイルを作る

rails generate migration AddOtherToUsers

名前は何やっているかわかるようなネーミングにした

マイグレーションファイルを編集する

class AddOtherToUsers < ActiveRecord::Migration
  def change
    add_column :users, :other, :integer, :after=>:campus
  end
end

テーブルを操作する

rake db:migrate
rake aborted!
ActiveRecord::StatementInvalid: Could not find table 'members'

見覚えのあるようおなエラー

rake db:migrate RAILS_ENV=production

流れに沿って作る。

new
#user_controller.rb
  def new
    @user = User.new
    @basyo = [false, false, false, false, false] #場所の初期値
  end
#new.html.erb
<%- if context=="edit" -%>
<%- if @user.campus !=1 %>
	A地区<%= check_box_tag 'basyo[0]', true, @basyo[0], {} %>
<%- end %>
<%- if @user.campus !=2 %>
	B地区<%= check_box_tag 'basyo[1]', true, @basyo[1], {} %>
<%- end %>
<%- if @user.campus !=4 %>
	C地区<%= check_box_tag 'basyo[2]', true, @basyo[2], {} %>
<%- end %>
<%- if @user.campus !=16 %>
	D地区<%= check_box_tag 'basyo[4]', true, @basyo[4], {} %>
<%- end %>
<%- end %>
create
  def create
    @user = User.new(params[:user])    
    @user.other = basyo_to_bit(params[:basyo])
(省略)
  # ビットを数値に変換する
  def basyo_to_bit(parameters)
    unless parameters.nil?
      rtn=0
      parameters.each{|key, value|
      rtn += 2**key.to_i if value == "true"
      }
    else
      rtn = nil
    end
    return rtn
  end
show
<%= other_edit(usr.other) %>
#users_helper.rb
  def other_edit(m)
    unless m.nil?
      rt =""
      $campuses.each{|c|
        #ビット演算
        if c[1] & m == c[1]
          rt += "/" unless rt.blank?
          rt += c[0] 
        end
        }
      return rt
    end
  end
edit

既存の未入力対策と初期値の設定、なんだかかっこわるい。

  def edit
    @user = User.find(params[:id])
    #logger.debug(@user.other)
    if @user.other.nil?
      @basyo = [false, false, false, false, false]
    else
      tmp = @user.other.to_s(2).split("")
      if tmp.size < 5
        (5-tmp.size).times{ tmp.unshift("0") }
      end
      @basyo = []
      tmp.each{|n|
        rt = n == "1" ? true : false
        @basyo << rt
        }
    end  
  end
 ||<
***update
>||
  def update
    @user = User.find(params[:id])
    @user.other = basyo_to_bit(params[:basyo])
(省略)