diff --git a/app/controllers/books_controller.rb b/app/controllers/books_controller.rb
index d13ffd9..c9761d4 100644
--- a/app/controllers/books_controller.rb
+++ b/app/controllers/books_controller.rb
@@ -16,6 +16,8 @@ def index
# GET /books/1
# GET /books/1.json
def show
+ session[:book_id]=@book.id
+
respond_to do |format|
format.html # show.html.erb
format.xml { render xml: @book }
diff --git a/app/controllers/memos_controller.rb b/app/controllers/memos_controller.rb
new file mode 100644
index 0000000..8ac6be5
--- /dev/null
+++ b/app/controllers/memos_controller.rb
@@ -0,0 +1,75 @@
+class MemosController < ApplicationController
+
+ # GET /memos/new
+ # GET /memos/new.json
+ def new
+ #Return to mainmenu if book value in session is nil
+ if session[:book_id].nil?
+ redirect_to books_path
+ return
+ end
+
+ @memo = Memo.new
+ @book = Book.find(session[:book_id])
+ @memo.book_id = @book.id
+
+ respond_to do |format|
+ format.html # new.html.erb
+ format.xml { render xml: @memo }
+ format.json { render json: @memo }
+ end
+ end
+
+ # POST /memos
+ # POST /memos.json
+ def create
+ #Return to mainmenu if book value in session is nil
+ if session[:book_id].nil?
+ redirect_to books_path
+ return
+ end
+
+ @memo = Memo.new(params[:memo])
+ @book = Book.find(session[:book_id])
+ @memo.book_id = @book.id
+
+ #Return to mainmenu if already logged in
+ if @memo.book_id.nil?
+ redirect_to @book
+ return
+ end
+
+ respond_to do |format|
+ if @memo.save
+ format.html { redirect_to @book }
+ format.xml { render xml: @memo, status: :created, location: @memo }
+ format.json { render json: @memo, status: :created, location: @memo }
+ else
+ format.html { render action: "new" }
+ format.xml { render xml: @memo.errors, status: :unprocessable_entity }
+ format.json { render json: @memo.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /memos/1
+ # DELETE /memos/1.json
+ def destroy
+ #Return to mainmenu if book value in session is nil
+ if session[:book_id].nil?
+ redirect_to books_path
+ return
+ end
+
+ @memo = Memo.find(params[:id])
+ @book = Book.find(session[:book_id])
+ @memo.destroy
+
+ respond_to do |format|
+ format.html { redirect_to @book }
+ format.xml { head :no_content }
+ format.json { head :no_content }
+ end
+ end
+
+end
diff --git a/app/helpers/memos_helper.rb b/app/helpers/memos_helper.rb
new file mode 100644
index 0000000..0e732a1
--- /dev/null
+++ b/app/helpers/memos_helper.rb
@@ -0,0 +1,2 @@
+module MemosHelper
+end
diff --git a/app/models/book.rb b/app/models/book.rb
index 95c42dd..28d1b52 100644
--- a/app/models/book.rb
+++ b/app/models/book.rb
@@ -1,11 +1,12 @@
# encoding: UTF-8
class Book < ActiveRecord::Base
- attr_accessible :memo, :purchased_on, :title
+ has_many :memos, :dependent => :destroy
+ attr_accessible :purchased_on, :title
validates :title, :presence => true
before_create :total_books_count
def total_books_count
- self.memo += "【 累計冊数#{Book.count + 1} 】"
+ #self.memo += "【 累計冊数#{Book.count + 1} 】"
end
end
diff --git a/app/models/memo.rb b/app/models/memo.rb
new file mode 100644
index 0000000..1f03146
--- /dev/null
+++ b/app/models/memo.rb
@@ -0,0 +1,7 @@
+class Memo < ActiveRecord::Base
+ attr_accessible :content
+
+ validates_length_of :content, :maximum => 100, :allow_blank => false, :message => "Memo must not be empty and must contain less than 100 characters"
+
+ belongs_to :book
+end
diff --git a/app/views/books/_form.html.erb b/app/views/books/_form.html.erb
index da45ee0..31176b7 100644
--- a/app/views/books/_form.html.erb
+++ b/app/views/books/_form.html.erb
@@ -15,10 +15,6 @@
<%= f.label :title %>
<%= f.text_field :title %>
-
- <%= f.label :memo %>
- <%= f.text_area :memo %>
-
<%= f.label :purchased_on %>
<%= f.date_select :purchased_on %>
diff --git a/app/views/books/index.html.erb b/app/views/books/index.html.erb
index 5f03ad6..be96b72 100644
--- a/app/views/books/index.html.erb
+++ b/app/views/books/index.html.erb
@@ -3,7 +3,7 @@
| Title |
- Memo |
+
Purchased on |
|
|
@@ -13,7 +13,7 @@
<% @books.each do |book| %>
| <%= book.title %> |
- <%= book.memo %> |
+
<%= book.purchased_on %> |
<%= link_to 'Show', book %> |
<%= link_to 'Edit', edit_book_path(book) %> |
diff --git a/app/views/books/show.html.erb b/app/views/books/show.html.erb
index 23005ab..8373c53 100644
--- a/app/views/books/show.html.erb
+++ b/app/views/books/show.html.erb
@@ -5,16 +5,25 @@
<%= @book.title %>
-
- Memo:
- <%= @book.memo %>
-
-
Purchased on:
<%= @book.purchased_on %>
+
+
+ | Memo (<%= link_to 'Add new', new_memo_path %>) |
+ |
+
+
+<% @book.memos.each do |memo| %>
+
+ | <%= memo.content %> |
+ <%= link_to 'Delete', memo, confirm: 'Are you sure?', method: :delete %> |
+
+<% end %>
+
+
<%= link_to 'Edit', edit_book_path(@book) %> |
<%= link_to 'Back', books_path %>
diff --git a/app/views/memos/_form.html.erb b/app/views/memos/_form.html.erb
new file mode 100644
index 0000000..dc838b4
--- /dev/null
+++ b/app/views/memos/_form.html.erb
@@ -0,0 +1,21 @@
+<%= form_for(@memo) do |f| %>
+ <% if @memo.errors.any? %>
+
+
<%= pluralize(@memo.errors.count, "memo") %> prohibited this memo from being saved:
+
+
+ <% @memo.errors.full_messages.each do |msg| %>
+ - <%= msg %>
+ <% end %>
+
+
+ <% end %>
+
+
+ <%= f.label :content %>
+ <%= f.text_area :content %>
+
+
+ <%= f.submit %>
+
+<% end %>
diff --git a/app/views/memos/new.html.erb b/app/views/memos/new.html.erb
new file mode 100644
index 0000000..af710ec
--- /dev/null
+++ b/app/views/memos/new.html.erb
@@ -0,0 +1,5 @@
+New memo
+
+<%= render 'form' %>
+
+<%= link_to 'Back', @book %>
diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb
index 8ed19e1..bf5f73a 100644
--- a/config/initializers/session_store.rb
+++ b/config/initializers/session_store.rb
@@ -1,8 +1,8 @@
# Be sure to restart your server when you modify this file.
-BookMemo2::Application.config.session_store :cookie_store, key: '_book_memo2_session'
+#BookMemo2::Application.config.session_store :cookie_store, key: '_book_memo2_session'
# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
-# BookMemo2::Application.config.session_store :active_record_store
+BookMemo2::Application.config.session_store :active_record_store
diff --git a/config/routes.rb b/config/routes.rb
index f3d38ab..d7adae1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,5 +1,6 @@
BookMemo2::Application.routes.draw do
resources :books
+ resources :memos
# The priority is based upon order of creation:
# first created -> highest priority.
diff --git a/db/migrate/20120526050801_create_books.rb b/db/migrate/20120526050801_create_books.rb
index b04e895..2ac8741 100644
--- a/db/migrate/20120526050801_create_books.rb
+++ b/db/migrate/20120526050801_create_books.rb
@@ -2,7 +2,7 @@ class CreateBooks < ActiveRecord::Migration
def change
create_table :books do |t|
t.string :title
- t.text :memo
+ #t.text :memo
t.date :purchased_on
t.timestamps
diff --git a/db/migrate/20120614114819_create_memos.rb b/db/migrate/20120614114819_create_memos.rb
new file mode 100644
index 0000000..d46d3bd
--- /dev/null
+++ b/db/migrate/20120614114819_create_memos.rb
@@ -0,0 +1,12 @@
+class CreateMemos < ActiveRecord::Migration
+ def change
+ create_table :memos do |t|
+
+ t.integer :book_id, :null =>false, :options =>
+ "CONSTRAINT fk_memo_books REFERENCES books(id)"
+ t.text :content
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20120614164222_add_sessions_table.rb b/db/migrate/20120614164222_add_sessions_table.rb
new file mode 100644
index 0000000..4c87956
--- /dev/null
+++ b/db/migrate/20120614164222_add_sessions_table.rb
@@ -0,0 +1,12 @@
+class AddSessionsTable < ActiveRecord::Migration
+ def change
+ create_table :sessions do |t|
+ t.string :session_id, :null => false
+ t.text :data
+ t.timestamps
+ end
+
+ add_index :sessions, :session_id
+ add_index :sessions, :updated_at
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 5fc61c2..1e5755b 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,14 +11,30 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120526050801) do
+ActiveRecord::Schema.define(:version => 20120614164222) do
create_table "books", :force => true do |t|
t.string "title"
- t.text "memo"
t.date "purchased_on"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
+ create_table "memos", :force => true do |t|
+ t.integer "book_id", :null => false
+ t.text "content"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
+ create_table "sessions", :force => true do |t|
+ t.string "session_id", :null => false
+ t.text "data"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
+ add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
+ add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
+
end
diff --git a/spec/controllers/books_controller_spec.rb b/spec/controllers/books_controller_spec.rb
index eb6727c..e638f91 100644
--- a/spec/controllers/books_controller_spec.rb
+++ b/spec/controllers/books_controller_spec.rb
@@ -24,7 +24,7 @@
# Book. As you add validations to Book, be sure to
# update the return value of this method accordingly.
def valid_attributes
- { title: 'book title', memo: '' }
+ { title: 'book title'}
end
# This should return the minimal set of values that should be in the session
diff --git a/spec/controllers/memos_controller_spec.rb b/spec/controllers/memos_controller_spec.rb
new file mode 100644
index 0000000..785443e
--- /dev/null
+++ b/spec/controllers/memos_controller_spec.rb
@@ -0,0 +1,96 @@
+require 'spec_helper'
+
+# This spec was generated by rspec-rails when you ran the scaffold generator.
+# It demonstrates how one might use RSpec to specify the controller code that
+# was generated by Rails when you ran the scaffold generator.
+#
+# It assumes that the implementation code is generated by the rails scaffold
+# generator. If you are using any extension libraries to generate different
+# controller code, this generated spec may or may not pass.
+#
+# It only uses APIs available in rails and/or rspec-rails. There are a number
+# of tools you can use to make these specs even more expressive, but we're
+# sticking to rails and rspec-rails APIs to keep things simple and stable.
+#
+# Compared to earlier versions of this generator, there is very limited use of
+# stubs and message expectations in this spec. Stubs are only used when there
+# is no simpler way to get a handle on the object needed for the example.
+# Message expectations are only used when there is no simpler way to specify
+# that an instance is receiving a specific message.
+
+describe MemosController do
+
+ # This should return the minimal set of attributes required to create a valid
+ # Memo. As you add validations to Memo, be sure to
+ # update the return value of this method accordingly.
+ def valid_attributes
+ {}
+ end
+
+ # This should return the minimal set of values that should be in the session
+ # in order to pass any filters (e.g. authentication) defined in
+ # MemosController. Be sure to keep this updated too.
+ def valid_session
+ {}
+ end
+
+ describe "GET new" do
+ it "assigns a new memo as @memo" do
+ get :new, {}, valid_session
+ assigns(:memo).should be_a_new(Memo)
+ end
+ end
+
+ describe "POST create" do
+ describe "with valid params" do
+ it "creates a new Memo" do
+ expect {
+ post :create, {:memo => valid_attributes}, valid_session
+ }.to change(Memo, :count).by(1)
+ end
+
+ it "assigns a newly created memo as @memo" do
+ post :create, {:memo => valid_attributes}, valid_session
+ assigns(:memo).should be_a(Memo)
+ assigns(:memo).should be_persisted
+ end
+
+ it "redirects to the created memo" do
+ post :create, {:memo => valid_attributes}, valid_session
+ response.should redirect_to(Memo.last)
+ end
+ end
+
+ describe "with invalid params" do
+ it "assigns a newly created but unsaved memo as @memo" do
+ # Trigger the behavior that occurs when invalid params are submitted
+ Memo.any_instance.stub(:save).and_return(false)
+ post :create, {:memo => {}}, valid_session
+ assigns(:memo).should be_a_new(Memo)
+ end
+
+ it "re-renders the 'new' template" do
+ # Trigger the behavior that occurs when invalid params are submitted
+ Memo.any_instance.stub(:save).and_return(false)
+ post :create, {:memo => {}}, valid_session
+ response.should render_template("new")
+ end
+ end
+ end
+
+ describe "DELETE destroy" do
+ it "destroys the requested memo" do
+ memo = Memo.create! valid_attributes
+ expect {
+ delete :destroy, {:id => memo.to_param}, valid_session
+ }.to change(Memo, :count).by(-1)
+ end
+
+ it "redirects to the memos list" do
+ memo = Memo.create! valid_attributes
+ delete :destroy, {:id => memo.to_param}, valid_session
+ response.should redirect_to(memos_url)
+ end
+ end
+
+end
diff --git a/spec/factories/books.rb b/spec/factories/books.rb
index 2047d44..7440785 100644
--- a/spec/factories/books.rb
+++ b/spec/factories/books.rb
@@ -4,7 +4,7 @@
FactoryGirl.define do
factory :book do
sequence(:title) { |n| "title_#{n}" }
- memo "this is memo"
+ #memo "this is memo"
purchased_on Time.now
end
end
diff --git a/spec/factories/memos.rb b/spec/factories/memos.rb
new file mode 100644
index 0000000..b571105
--- /dev/null
+++ b/spec/factories/memos.rb
@@ -0,0 +1,8 @@
+# Read about factories at https://github.com/thoughtbot/factory_girl
+
+FactoryGirl.define do
+ factory :memo do
+ book_id 1
+ content "this is memo"
+ end
+end
diff --git a/spec/helpers/memos_helper_spec.rb b/spec/helpers/memos_helper_spec.rb
new file mode 100644
index 0000000..48b8f0a
--- /dev/null
+++ b/spec/helpers/memos_helper_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+# Specs in this file have access to a helper object that includes
+# the MemosHelper. For example:
+#
+# describe MemosHelper do
+# describe "string concat" do
+# it "concats two strings with spaces" do
+# helper.concat_strings("this","that").should == "this that"
+# end
+# end
+# end
+describe MemosHelper do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/book_spec.rb b/spec/models/book_spec.rb
index f820855..21a4b99 100644
--- a/spec/models/book_spec.rb
+++ b/spec/models/book_spec.rb
@@ -11,11 +11,11 @@
end
end
- describe '#total_books_count' do
- let(:book){ FactoryGirl.build :book }
- before { book.save }
- it "memoに累計冊数が表示されること" do
- book.memo.should include "【 累計冊数#{Book.count} 】"
- end
- end
+ #describe '#total_books_count' do
+ # let(:book){ FactoryGirl.build :book }
+ # before { book.save }
+ # it "memoに累計冊数が表示されること" do
+ # book.memo.should include "【 累計冊数#{Book.count} 】"
+ # end
+ #end
end
diff --git a/spec/models/memo_spec.rb b/spec/models/memo_spec.rb
new file mode 100644
index 0000000..4d570d3
--- /dev/null
+++ b/spec/models/memo_spec.rb
@@ -0,0 +1,27 @@
+# coding:utf-8
+require 'spec_helper'
+
+describe Memo do
+ describe 'validation' do
+ describe 'content' do
+ subject { Memo.new.valid? }
+ it '未入力の場合はエラー' do
+ should be_false
+ end
+ end
+ end
+
+describe "#new" do
+ let(:memo){ FactoryGirl.build :memo }
+ it "takes content and book_id and returns a Memo object" do
+ @memo.should be_an_instance_of Memo
+ end
+end
+
+describe "#content" do
+ let(:memo){ FactoryGirl.build :memo }
+ it "returns the correct content" do
+ @memo.content.should eql "this is memo"
+ end
+end
+end
diff --git a/spec/requests/memos_spec.rb b/spec/requests/memos_spec.rb
new file mode 100644
index 0000000..66ea594
--- /dev/null
+++ b/spec/requests/memos_spec.rb
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+require 'spec_helper'
+
+describe "Memos" do
+ describe "GET /memos" do
+ it "works! (now write some real specs)" do
+ # Run the generator again with the --webrat flag if you want to use webrat methods/matchers
+ #get memos_path
+ #response.status.should be(200)
+ let!(:book){ FactoryGirl.create :book }
+ subject { page }
+
+ visit "/memos/new"
+
+ context "with adding" do
+ let!(:orgcount){ book.memos.length }
+
+ before do
+ fill_in "memo[content]", with: "dummydummy"
+ click_on 'Create Memo'
+ end
+
+ it "ページが遷移されていること" do
+ current_path.should == book_path(book)
+ end
+
+ it "メモが追加されていること" do
+ should have_content book.memos.length
+ book.memos.length.should == (orgcount + 1)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/routing/memos_routing_spec.rb b/spec/routing/memos_routing_spec.rb
new file mode 100644
index 0000000..b0f68f9
--- /dev/null
+++ b/spec/routing/memos_routing_spec.rb
@@ -0,0 +1,35 @@
+require "spec_helper"
+
+describe MemosController do
+ describe "routing" do
+
+ it "routes to #index" do
+ get("/memos").should route_to("memos#index")
+ end
+
+ it "routes to #new" do
+ get("/memos/new").should route_to("memos#new")
+ end
+
+ it "routes to #show" do
+ get("/memos/1").should route_to("memos#show", :id => "1")
+ end
+
+ it "routes to #edit" do
+ get("/memos/1/edit").should route_to("memos#edit", :id => "1")
+ end
+
+ it "routes to #create" do
+ post("/memos").should route_to("memos#create")
+ end
+
+ it "routes to #update" do
+ put("/memos/1").should route_to("memos#update", :id => "1")
+ end
+
+ it "routes to #destroy" do
+ delete("/memos/1").should route_to("memos#destroy", :id => "1")
+ end
+
+ end
+end
diff --git a/spec/views/books/edit.html.erb_spec.rb b/spec/views/books/edit.html.erb_spec.rb
index 87484cb..02714a2 100644
--- a/spec/views/books/edit.html.erb_spec.rb
+++ b/spec/views/books/edit.html.erb_spec.rb
@@ -14,7 +14,6 @@
# Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "form", :action => books_path(@book), :method => "post" do
assert_select "input#book_title", :name => "book[title]"
- assert_select "textarea#book_memo", :name => "book[memo]"
end
end
end
diff --git a/spec/views/books/index.html.erb_spec.rb b/spec/views/books/index.html.erb_spec.rb
index 190efa1..5cfbff6 100644
--- a/spec/views/books/index.html.erb_spec.rb
+++ b/spec/views/books/index.html.erb_spec.rb
@@ -5,11 +5,11 @@
assign(:books, [
stub_model(Book,
:title => "Title",
- :memo => "MyText"
+ #:memo => "MyText"
),
stub_model(Book,
:title => "Title",
- :memo => "MyText"
+ #:memo => "MyText"
)
])
end
@@ -18,6 +18,6 @@
render
# Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "tr>td", :text => "Title".to_s, :count => 2
- assert_select "tr>td", :text => "MyText".to_s, :count => 2
+ #assert_select "tr>td", :text => "MyText".to_s, :count => 2
end
end
diff --git a/spec/views/books/new.html.erb_spec.rb b/spec/views/books/new.html.erb_spec.rb
index e9c5dc7..5a63498 100644
--- a/spec/views/books/new.html.erb_spec.rb
+++ b/spec/views/books/new.html.erb_spec.rb
@@ -4,7 +4,7 @@
before(:each) do
assign(:book, stub_model(Book,
:title => "MyString",
- :memo => "MyText"
+ #:memo => "MyText"
).as_new_record)
end
@@ -14,7 +14,7 @@
# Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "form", :action => books_path, :method => "post" do
assert_select "input#book_title", :name => "book[title]"
- assert_select "textarea#book_memo", :name => "book[memo]"
+ #assert_select "textarea#book_memo", :name => "book[memo]"
end
end
end
diff --git a/spec/views/books/show.html.erb_spec.rb b/spec/views/books/show.html.erb_spec.rb
index 82d0e4b..c0ea12f 100644
--- a/spec/views/books/show.html.erb_spec.rb
+++ b/spec/views/books/show.html.erb_spec.rb
@@ -4,7 +4,7 @@
before(:each) do
@book = assign(:book, stub_model(Book,
:title => "Title",
- :memo => "MyText"
+ #:memo => "MyText"
))
end
@@ -12,6 +12,6 @@
render
# Run the generator again with the --webrat flag if you want to use webrat matchers
rendered.should match(/Title/)
- rendered.should match(/MyText/)
+ #rendered.should match(/MyText/)
end
end
diff --git a/spec/views/memos/new.html.erb_spec.rb b/spec/views/memos/new.html.erb_spec.rb
new file mode 100644
index 0000000..329d838
--- /dev/null
+++ b/spec/views/memos/new.html.erb_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe "memos/new" do
+ before(:each) do
+ assign(:memo, stub_model(Memo).as_new_record)
+ end
+
+ it "renders new memo form" do
+ render
+
+ # Run the generator again with the --webrat flag if you want to use webrat matchers
+ assert_select "form", :action => memos_path, :method => "post" do
+ end
+ end
+end