Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

search_baseの仮組み

  • Loading branch information...
commit dc6f78e8f8abe26f3b6cc98c52abf50ae4309d0e 1 parent 54fec24
yoshimi authored
Showing with 371 additions and 137 deletions.
  1. +1 −0  .gitignore
  2. +4 −0 lib/railstar.rb
  3. +39 −0 lib/railstar/active_record_ext.rb
  4. +92 −0 lib/railstar/search_base.rb
  5. +2 −1  test/dummy/app/controllers/projects_controller.rb
  6. +32 −54 test/dummy/app/controllers/tasks_controller.rb
  7. +14 −0 test/dummy/app/models/search/project.rb
  8. +18 −0 test/dummy/app/models/search/task.rb
  9. +2 −1  test/dummy/app/views/general/index.html.erb
  10. +10 −5 test/dummy/app/views/projects/index.html.erb
  11. +8 −0 test/dummy/app/views/tasks/_detail.html.erb
  12. +14 −26 test/dummy/app/views/tasks/_form.html.erb
  13. +9 −0 test/dummy/app/views/tasks/confirm.html.erb
  14. +12 −0 test/dummy/app/views/tasks/destroy.html.erb
  15. +6 −4 test/dummy/app/views/tasks/edit.html.erb
  16. +35 −21 test/dummy/app/views/tasks/index.html.erb
  17. +5 −3 test/dummy/app/views/tasks/new.html.erb
  18. +6 −18 test/dummy/app/views/tasks/show.html.erb
  19. +3 −2 test/dummy/config/routes.rb
  20. +2 −1  test/dummy/db/migrate/20120305073308_create_tasks.rb
  21. +2 −1  test/dummy/db/schema.rb
  22. +4 −0 test/dummy/db/seeds.rb
  23. +6 −0 test/dummy/resources/code/status.csv
  24. +11 −0 test/dummy/resources/db/projects.yml
  25. +34 −0 test/dummy/resources/db/tasks.yml
View
1  .gitignore
@@ -5,3 +5,4 @@ test/dummy/db/*.sqlite3
test/dummy/log/*.log
test/dummy/tmp/
test/dummy/.sass-cache
+.DS_Store
View
4 lib/railstar.rb
@@ -1,7 +1,11 @@
require 'railstar/engine'
require 'railstar/code_holder'
+require 'railstar/search_base'
+
require 'railstar/helper'
ActionView::Base.send(:include, Railstar::Helper)
+require 'railstar/active_record_ext'
+ActiveRecord::Base.send(:include, Railstar::ActiveRecordExt)
module Railstar
def self.env
View
39 lib/railstar/active_record_ext.rb
@@ -0,0 +1,39 @@
+# encoding: utf-8
+module Railstar
+ module ActiveRecordExt
+ module ClassMethods
+ def truncation
+ return if self.count > 0
+ self.truncation!
+ end
+
+ def truncation!
+ table_name = self.to_s.underscore.pluralize
+ file_name = "#{table_name}.yml"
+ file_path = File.join(Rails.root, "resources", "db", file_name)
+ raise "#{file_path} file not found." unless File.exist?(file_path)
+ self.transaction do
+ case self.connection.adapter_name
+ when "SQLite"
+ self.connection.execute("DELETE FROM `#{self.table_name}`")
+ else
+ self.connection.execute("TRUNCATE TABLE `#{self.table_name}`")
+ end
+ YAML.load_file(file_path).each do |key, value|
+ self.create value
+ end
+ end
+ end
+ end
+
+ module InstanceMethods
+ end
+
+ def self.included(base)
+ base.extend ClassMethods
+ base.class_eval do
+ include InstanceMethods
+ end
+ end
+ end
+end
View
92 lib/railstar/search_base.rb
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+module Railstar
+ class SearchBase
+ attr_accessor :where, :values
+
+ def initialize(hash)
+ self.where = []
+ self.values = {}
+ if hash
+ hash.each do |k,v|
+ send("#{k}=", v)
+ end
+ end
+ end
+
+ def to_params
+ ret = {}
+ TARGET_COLUMN.each do |c|
+ unless eval(c.to_s).blank?
+ ret[c] = eval(c.to_s)
+ end
+ end
+ return ret
+ end
+
+ def to_str_params
+ ret = to_params.map do |k,v|
+ begin
+ "#{k}=#{CGI.escape(v)}"
+ rescue
+ end
+ end
+ ret.join("&")
+ end
+
+ def base
+ create_conditions #TODO: 毎回条件作成をしないようにしたい
+ target_model.where([self.where.join(" AND "), values])
+ end
+
+ private
+ def like(method, options={})
+ value = eval(method.to_s)
+ unless value.blank?
+ column = options[:column] || method
+ self.where << "#{with_table_name(options[:table_name],column)} like :#{method}"
+ self.values[method] = "%#{value}%"
+ end
+ end
+
+ def eq(method, options={})
+ compare(method, "=", options)
+ end
+
+ def inc(method, options={})
+ value = eval(method.to_s)
+ value = value.split(",") if value.is_a?(String) && value.include?(",")
+ unless value.blank?
+ column = options[:column] || method
+ self.where << "#{with_table_name(options[:table_name],column)} in (:#{method})"
+ self.values[method] = value
+ end
+ end
+
+ def compare(method, sign, options={})
+ return unless sign =~ /^[<>=]{1,2}$/
+ value = eval(method.to_s)
+ unless value.blank?
+ column = options[:column] || method
+ self.where << "#{with_table_name(options[:table_name],column)} #{sign} :#{method}"
+ self.values[method] = value
+ end
+ end
+
+ def bit(method, options={})
+ value = eval(method.to_s)
+ unless value.blank?
+ column = options[:column] || method
+ self.where << "#{with_table_name(options[:table_name],column)} & :#{method} = :#{method}"
+ self.values[method] = value
+ end
+ end
+
+
+ def with_table_name table_name, method
+ ret = ""
+ ret << "#{table_name || target_model.table_name}." if table_name
+ ret << method.to_s
+ ret
+ end
+ end
+end
View
3  test/dummy/app/controllers/projects_controller.rb
@@ -5,7 +5,8 @@
class ProjectsController < ApplicationController
def index
- @projects = Project.order("created_at desc").all
+ @search = Search::Project.new(params[:search])
+ @projects = @search.base.joins("inner join tasks on tasks.project_id = projects.id").order("created_at desc").group("projects.id").all
end
def show
View
86 test/dummy/app/controllers/tasks_controller.rb
@@ -1,83 +1,61 @@
+# -*- coding: utf-8 -*-
+# destroyメソッドに注意。モバイル対応&テキストリンク利用のためイレギュラーなことをしている
+# restに対応した形を徹底したい場合は、削除確認ページへのリンクを以下の様に、formにする
+# <%= form_tag(Task_path(task, :mode => "draft"), :method=>:delete) do %><%= submit_tag "delete", :name => "delete" %><% end %>
+
class TasksController < ApplicationController
- # GET /tasks
- # GET /tasks.json
def index
- @tasks = Task.all
-
- respond_to do |format|
- format.html # index.html.erb
- format.json { render json: @tasks }
- end
+ @search = Search::Task.new(params[:search])
+ @search.project_id = params[:project_id]
+ @tasks = @search.base.order("created_at desc").all
end
- # GET /tasks/1
- # GET /tasks/1.json
def show
@task = Task.find(params[:id])
-
- respond_to do |format|
- format.html # show.html.erb
- format.json { render json: @task }
- end
+ render "destroy" if params[:mode] == "draft"
end
- # GET /tasks/new
- # GET /tasks/new.json
def new
- @task = Task.new
-
- respond_to do |format|
- format.html # new.html.erb
- format.json { render json: @task }
- end
+ @task = Task.new(params[:task])
end
- # GET /tasks/1/edit
def edit
@task = Task.find(params[:id])
end
- # POST /tasks
- # POST /tasks.json
def create
@task = Task.new(params[:task])
-
- respond_to do |format|
- if @task.save
- format.html { redirect_to @task, notice: 'Task was successfully created.' }
- format.json { render json: @task, status: :created, location: @task }
- else
- format.html { render action: "new" }
- format.json { render json: @task.errors, status: :unprocessable_entity }
- end
- end
+ save
end
- # PUT /tasks/1
- # PUT /tasks/1.json
def update
@task = Task.find(params[:id])
-
- respond_to do |format|
- if @task.update_attributes(params[:task])
- format.html { redirect_to @task, notice: 'Task was successfully updated.' }
- format.json { head :no_content }
- else
- format.html { render action: "edit" }
- format.json { render json: @task.errors, status: :unprocessable_entity }
- end
- end
+ @task.attributes = params[:task]
+ save
end
- # DELETE /tasks/1
- # DELETE /tasks/1.json
def destroy
@task = Task.find(params[:id])
- @task.destroy
+ if params.key?("back")
+ redirect_to(task_url)
+ elsif params[:mode] != "draft"
+ @task.destroy
+ redirect_to(task_url, :notice => "deleted success.")
+ end
+ end
- respond_to do |format|
- format.html { redirect_to tasks_url }
- format.json { head :no_content }
+
+ private
+ def save
+ if !params.key?("back") && @task.valid?
+ if params[:mode] == "draft"
+ render :action => 'confirm'
+ else
+ @task.save!
+ redirect_to task_path(@task), :notice => 'saved success.'
+ end
+ else
+ render (@task.new_record? ? :new : :edit)
end
end
end
View
14 test/dummy/app/models/search/project.rb
@@ -0,0 +1,14 @@
+class Search::Project < Railstar::SearchBase
+ TARGET_COLUMN = %w(name like_name)
+ attr_accessor *TARGET_COLUMN
+
+ private
+ def create_conditions
+ eq(:name)
+ like(:like_name, column: :name, table_name: "tasks")
+ end
+
+ def target_model
+ ::Project
+ end
+end
View
18 test/dummy/app/models/search/task.rb
@@ -0,0 +1,18 @@
+class Search::Task < Railstar::SearchBase
+ TARGET_COLUMN = %w(name like_name status project_id from_price to_price)
+ attr_accessor *TARGET_COLUMN
+
+ private
+ def create_conditions
+ eq(:project_id)
+ eq(:name)
+ like(:like_name, column: :name)
+ inc(:status)
+ compare(:from_price, ">=", column: :price)
+ compare(:to_price, "<=", column: :price)
+ end
+
+ def target_model
+ ::Task
+ end
+end
View
3  test/dummy/app/views/general/index.html.erb
@@ -1 +1,2 @@
-<%= link_to "Railstar", railstar.root_path %>
+<%= link_to "Railstar", railstar.root_path %><br />
+<%= link_to "TestProject", projects_path %><br />
View
15 test/dummy/app/views/projects/index.html.erb
@@ -1,10 +1,16 @@
<h1>Listing projects</h1>
+<%= form_tag(nil, :method => :get) do %>
+<%= label :search, :name %>:<%= text_field :search, :name %><br />
+<%= label :search, :like_name %>:<%= text_field :search, :like_name %><br />
+<%= submit_tag :search %>
+<% end %>
+
<table>
<thead>
<tr>
- <th>Name</th>
- <th></th>
+ <th>Name</th>
+ <th></th>
<th></th>
<th></th>
</tr>
@@ -14,9 +20,8 @@
<tbody>
<% @projects.each do |project| %>
<tr>
- <th>Name</th>
- <td><%= project.name %></td>
- <td><%= link_to 'Show', project %></td>
+ <td><%= link_to project.name, project_tasks_path(:project_id => project.id) %></td>
+ <td><%= link_to 'Show', project %></td>
<td><%= link_to 'Edit', edit_project_path(project) %></td>
<td><%= link_to 'Delete', project_path(project, :mode => "draft") %></td>
</tr>
View
8 test/dummy/app/views/tasks/_detail.html.erb
@@ -0,0 +1,8 @@
+<table class="bordered-table zebra-striped">
+
+ <tr>
+ <th>Name</th>
+ <td><%= @task.name %></td>
+ </tr>
+
+</table>
View
40 test/dummy/app/views/tasks/_form.html.erb
@@ -1,29 +1,17 @@
-<%= form_for(@task) do |f| %>
- <% if @task.errors.any? %>
- <div id="error_explanation">
- <h2><%= pluralize(@task.errors.count, "error") %> prohibited this task from being saved:</h2>
+<%= form_for(@task, :url => save_action(@task, :mode => "draft")) do |f| %>
+<% if @task.errors.any? %>
+<% @task.errors.full_messages.each do |msg| %>
+<p><%= msg %></p>
+<% end %>
+<% end %>
+
- <ul>
- <% @task.errors.full_messages.each do |msg| %>
- <li><%= msg %></li>
- <% end %>
- </ul>
- </div>
- <% end %>
+<table class="bordered-table zebra-striped">
+ <tr>
+ <th><%= f.label :name %></th>
+ <td><%= f.text_field :name %></td>
+ </tr>
+</table>
- <div class="field">
- <%= f.label :name %><br />
- <%= f.text_field :name %>
- </div>
- <div class="field">
- <%= f.label :project_id %><br />
- <%= f.number_field :project_id %>
- </div>
- <div class="field">
- <%= f.label :status %><br />
- <%= f.number_field :status %>
- </div>
- <div class="actions">
- <%= f.submit %>
- </div>
+<%= f.submit :class => "btn primary" %>
<% end %>
View
9 test/dummy/app/views/tasks/confirm.html.erb
@@ -0,0 +1,9 @@
+<h1>Confirm task</h1>
+
+<%= render :partial => 'detail' %>
+
+<%= form_tag({}, :method => request.request_method) do %>
+<%= raw params_to_hidden_tag :task %>
+<input type="submit" value="戻る" name="back" class="btn" />
+<input type="submit" value="保存" class="btn primary" />
+<% end %>
View
12 test/dummy/app/views/tasks/destroy.html.erb
@@ -0,0 +1,12 @@
+<h1>Destroy task</h1>
+
+<%= render :partial => 'detail' %>
+
+<%= form_tag({}, :method => "delete") do -%>
+ <input type="submit" value="Cancel" name="back" class="btn" />
+ <input type="submit" value="Destroy" class="btn error" />
+<% end -%>
+
+<div>
+ <%= link_to 'Back', tasks_path, :class => "btn" %>
+</div>
View
10 test/dummy/app/views/tasks/edit.html.erb
@@ -1,6 +1,8 @@
-<h1>Editing task</h1>
+<h1>Editing project</h1>
-<%= render 'form' %>
+<%= render :partial => 'form' %>
-<%= link_to 'Show', @task %> |
-<%= link_to 'Back', tasks_path %>
+<div>
+ <%= link_to 'Show', project_path(@project), :class => "btn" %>
+ <%= link_to 'Back', projects_path, :class => "btn" %>
+</div>
View
56 test/dummy/app/views/tasks/index.html.erb
@@ -1,27 +1,41 @@
<h1>Listing tasks</h1>
-<table>
- <tr>
- <th>Name</th>
- <th>Project</th>
- <th>Status</th>
- <th></th>
- <th></th>
- <th></th>
- </tr>
+<%= form_tag(nil, :method => :get) do %>
+<%= label :search, :name %><%= text_field :search, :name %><br />
+<%= label :search, :like_name %><%= text_field :search, :like_name %><br />
+<% C.status.to_opt.each do |status| %>
+<%= label :search, "status_#{status.first}" %><%= check_box_tag "search[status][]", status.last, !!@search.status ? @search.status.detect{|s| s == status.last} : false %>
+<% end %><br />
+<%= label :search, :price %><%= text_field :search, :from_price %><%= text_field :search, :to_price %><br />
-<% @tasks.each do |task| %>
- <tr>
- <td><%= task.name %></td>
- <td><%= task.project_id %></td>
- <td><%= task.status %></td>
- <td><%= link_to 'Show', task %></td>
- <td><%= link_to 'Edit', edit_task_path(task) %></td>
- <td><%= link_to 'Destroy', task, confirm: 'Are you sure?', method: :delete %></td>
- </tr>
+<%= submit_tag :search %>
<% end %>
-</table>
-<br />
+<table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Status</th>
+ <th>Price</th>
+ <th></th>
+ <th></th>
+ <th></th>
+ </tr>
+ </thead>
+
+
+ <tbody>
+ <% @tasks.each do |task| %>
+ <tr>
+ <td><%= task.name %></td>
+ <td><%= C.status[task.status].name %></td>
+ <td><%= task.price %></td>
+ <td><%= link_to 'Show', project_task_path(:id => task.id) %></td>
+ <td><%#= link_to 'Edit', edit_task_path(task) %></td>
+ <td><%#= link_to 'Delete', task_path(task, :mode => "draft") %></td>
+ </tr>
+ <% end %>
+ </tbody>
+</table>
-<%= link_to 'New Task', new_task_path %>
+<%= link_to 'New Task', new_project_task_path %>
View
8 test/dummy/app/views/tasks/new.html.erb
@@ -1,5 +1,7 @@
-<h1>New task</h1>
+<h1>New project</h1>
-<%= render 'form' %>
+<%= render :partial => 'form' %>
-<%= link_to 'Back', tasks_path %>
+<div>
+ <%= link_to 'Back', projects_path, :class => "btn" %>
+</div>
View
24 test/dummy/app/views/tasks/show.html.erb
@@ -1,20 +1,8 @@
-<p id="notice"><%= notice %></p>
+<h1>Showing project</h1>
+<%= render :partial => 'detail' %>
-<p>
- <b>Name:</b>
- <%= @task.name %>
-</p>
+<div>
+ <%= link_to 'Edit', edit_project_path(@project), :class => "btn" %>
+ <%= link_to 'Back', projects_path, :class => "btn" %>
+</div>
-<p>
- <b>Project:</b>
- <%= @task.project_id %>
-</p>
-
-<p>
- <b>Status:</b>
- <%= @task.status %>
-</p>
-
-
-<%= link_to 'Edit', edit_task_path(@task) %> |
-<%= link_to 'Back', tasks_path %>
View
5 test/dummy/config/routes.rb
@@ -1,7 +1,8 @@
Rails.application.routes.draw do
root :to => "general#index"
- resources :projects
- resources :tasks
+ resources :projects do
+ resources :tasks
+ end
mount Railstar::Engine => "/railstar"
end
View
3  test/dummy/db/migrate/20120305073308_create_tasks.rb
@@ -3,7 +3,8 @@ def change
create_table :tasks do |t|
t.string :name
t.integer :project_id
- t.integer :status
+ t.string :status
+ t.integer :price
t.timestamps
end
View
3  test/dummy/db/schema.rb
@@ -22,7 +22,8 @@
create_table "tasks", :force => true do |t|
t.string "name"
t.integer "project_id"
- t.integer "status"
+ t.string "status"
+ t.integer "price"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
View
4 test/dummy/db/seeds.rb
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+
+Project.truncation!
+Task.truncation!
View
6 test/dummy/resources/code/status.csv
@@ -0,0 +1,6 @@
+title,ステータス
+#DATA
+key,value,position,name
+TODO,todo,1,TODO
+DOING,doing,2,DOING
+DONE,done,3,DONE
View
11 test/dummy/resources/db/projects.yml
@@ -0,0 +1,11 @@
+1:
+ id: 1
+ name: プロジェクト1
+
+2:
+ id: 2
+ name: プロジェクト2
+
+3:
+ id: 3
+ name: プロジェクト3
View
34 test/dummy/resources/db/tasks.yml
@@ -0,0 +1,34 @@
+1:
+ project_id: 1
+ name: タスク1
+ status: "todo"
+ price: 100
+
+2:
+ project_id: 1
+ name: タスク2
+ status: "todo"
+ price: 200
+
+3:
+ project_id: 1
+ name: タスク3
+ status: "doing"
+ price: 200
+
+4:
+ project_id: 1
+ name: タスク4
+ status: "doing"
+ price: 300
+
+5:
+ project_id: 1
+ name: タスク5
+ status: "done"
+ price: 400
+
+6:
+ project_id: 2
+ name: タスク6
+ status: "todo"
Please sign in to comment.
Something went wrong with that request. Please try again.