C言語のプログラムをアップロードして,それを行番号をつけて表示したい(SyntaxHighlighterを使って)
ユーザ名とチェック済みかどうかも入力できるようにする.
edit時にfile_fieldの初期値としてファイル名を保持することはできないようである.
edit時の画面として,「選択されていません」と出力されるのは気持ち悪いが仕方がない...
プロジェクト作成
$ rails new codeupload
$ cd codeupload
モデル
$ rails g scaffold code filename:string file:binary done:boolean user:string
$ rake db:migrate
ルーティング
config/routes.rb
resources :codes
root 'codes#index'
ここで,localhost:3000で,動作確認する.
Views
フォーム
app/views/codes/_form.html.erb
<%= form_for(@code, html: {multipart: true}) do |f| %>
<% if @code.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@code.errors.count, "error") %> prohibited this code from being saved:</h2>
<ul>
<% @code.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :file %><br>
<%= f.file_field :file %>
</div>
<div class="field">
<%= f.label :done %><br>
<%= f.check_box :done %>
</div>
<div class="field">
<%= f.label :user %><br>
<%= f.text_field :user %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
index
アップロードしたC言語のプログラムをここで出力すると見にくいので,fileのところを消した.
プログラムはshowで見るようにする.
app/views/codes/index.html.erb
<h1>Listing codes</h1>
<table>
<thead>
<tr>
<th>Filename</th>
<th>Done</th>
<th>User</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @codes.each do |code| %>
<tr>
<td><%= code.filename %></td>
<td><%= code.done %></td>
<td><%= code.user %></td>
<td><%= link_to 'Show', code %></td>
<td><%= link_to 'Edit', edit_code_path(code) %></td>
<td><%= link_to 'Destroy', code, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Code', new_code_path %>
show
syntaxhighlighterでC言語を綺麗に出力するための部分も,ここで既に書いた.
app/views/codes/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Filename:</strong>
<%= @code.filename %>
</p>
<p>
<strong>File:</strong>
<pre class="brush: c">
<%= @code.file %>
</pre>
</p>
<p>
<strong>Done:</strong>
<%= @code.done %>
</p>
<p>
<strong>User:</strong>
<%= @code.user %>
</p>
<%= link_to 'Edit', edit_code_path(@code) %> |
<%= link_to 'Back', codes_path %>
コントローラー
app/controllers/codes_controller.rb
class CodesController < ApplicationController
before_action :set_code, only: [:show, :edit, :update, :destroy]
# GET /codes
# GET /codes.json
def index
@codes = Code.all
end
# GET /codes/1
# GET /codes/1.json
def show
end
# GET /codes/new
def new
@code = Code.new
end
# GET /codes/1/edit
def edit
end
# POST /codes
# POST /codes.json
def create
f = code_params[:file]
code = {}
if f != nil
code[:filename] = f.original_filename
code[:file] = f.read
end
code[:user] = code_params[:user]
code[:done] = code_params[:done]
@code = Code.new(code)
respond_to do |format|
if @code.save
format.html { redirect_to @code, notice: 'Code was successfully created.' }
format.json { render :show, status: :created, location: @code }
else
format.html { render :new }
format.json { render json: @code.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /codes/1
# PATCH/PUT /codes/1.json
def update
f = code_params[:file]
code = {}
if f != nil
code[:filename] = f.original_filename
code[:file] = f.read
end
code[:user] = code_params[:user]
code[:done] = code_params[:done]
respond_to do |format|
if @code.update(code)
format.html { redirect_to @code, notice: 'Code was successfully updated.' }
format.json { render :show, status: :ok, location: @code }
else
format.html { render :edit }
format.json { render json: @code.errors, status: :unprocessable_entity }
end
end
end
# DELETE /codes/1
# DELETE /codes/1.json
def destroy
@code.destroy
respond_to do |format|
format.html { redirect_to codes_url, notice: 'Code was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_code
@code = Code.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def code_params
params.require(:code).permit(:filename, :file, :done, :user)
end
end
ここで,localhost:3000にアクセスして,ファイルのアップロードができるかチェックする.
ここからSyntaxHighlighterの設定
http://alexgorbatchev.com/SyntaxHighlighter/
からsyntaxhighlighter_3.0.83.zipをダウンロードする(2014年9月9日現在).
$ unzip syntaxhighlighter_3.0.83.zip
展開したら,その中にあるstylesとscriptsのディレクトリをapp/publicにディレクトリごとコピーする.
$ cd syntaxhighlighter_3.0.83
$ cp -r styles scripts (適切なpath)/codeupload/public
app/views/codes/show.html.erb
<pre class="brush: c">
<%= @code.file %>
</pre>
以下を,headの最後の追加
app/views/layouts/application.html.erb
<link type="text/css" rel="stylesheet" href="/styles/shCore.css"/>
<link type="text/css" rel="Stylesheet" href="/styles/shThemeDefault.css" />
<script type="text/javascript" src="/scripts/XRegExp.js"></script>
<script type="text/javascript" src="/scripts/shCore.js"></script>
<script type="text/javascript" src="/scripts/shAutoloader.js"></script>
以下をbodyの最後に追加.
<script type="text/javascript">
SyntaxHighlighter.autoloader('cpp c ../scripts/shBrushCpp.js');
SyntaxHighlighter.all();
</script>
つまり,以下になる.
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Codeupload</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<link type="text/css" rel="stylesheet" href="/styles/shCore.css"/>
<link type="text/css" rel="Stylesheet" href="/styles/shThemeDefault.css" />
<script type="text/javascript" src="/scripts/XRegExp.js"></script>
<script type="text/javascript" src="/scripts/shCore.js"></script>
<script type="text/javascript" src="/scripts/shAutoloader.js"></script>
</head>
<body>
<%= yield %>
<script type="text/javascript">
SyntaxHighlighter.autoloader('cpp c ../scripts/shBrushCpp.js');
SyntaxHighlighter.all();
</script>
</body>
</html>