diff --git a/app/assets/javascripts/detailmemos.js.coffee b/app/assets/javascripts/detailmemos.js.coffee new file mode 100644 index 0000000..7615679 --- /dev/null +++ b/app/assets/javascripts/detailmemos.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/detailmemos.css.scss b/app/assets/stylesheets/detailmemos.css.scss new file mode 100644 index 0000000..fd6c97a --- /dev/null +++ b/app/assets/stylesheets/detailmemos.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the detailmemos controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/books_controller.rb b/app/controllers/books_controller.rb index d13ffd9..150b515 100644 --- a/app/controllers/books_controller.rb +++ b/app/controllers/books_controller.rb @@ -1,5 +1,6 @@ class BooksController < ApplicationController before_filter :find_book, :only => [:show, :destroy, :edit, :update] + before_filter :find_memo, :only => :show # GET /books # GET /books.json @@ -89,4 +90,11 @@ def destroy def find_book @book = Book.find(params[:id]) end + + private + def find_memo + @memos = Detailmemo.find_all_by_book_id(params[:id]) + p @memos + end + end diff --git a/app/controllers/detailmemos_controller.rb b/app/controllers/detailmemos_controller.rb new file mode 100644 index 0000000..efc71f0 --- /dev/null +++ b/app/controllers/detailmemos_controller.rb @@ -0,0 +1,40 @@ +class DetailmemosController < ApplicationController + # GET /detailmemos/new + # GET /detailmemos/new.json + def new + @detailmemo = Detailmemo.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @detailmemo } + end + end + + # POST /detailmemos + # POST /detailmemos.json + def create + @detailmemo = Detailmemo.new(params[:detailmemo]) + + respond_to do |format| + if @detailmemo.save + format.html { redirect_to Book, notice: 'Detailmemo was successfully created.' } + format.json { render json: @detailmemo, status: :created, location: @detailmemo } + else + format.html { render action: "new" } + format.json { render json: @detailmemo.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /detailmemos/1 + # DELETE /detailmemos/1.json + def destroy + @detailmemo = Detailmemo.find(params[:id]) + @detailmemo.destroy + + respond_to do |format| + format.html { redirect_to book_path(@detailmemo[:book_id]) } + format.json { head :no_content } + end + end +end diff --git a/app/helpers/detailmemos_helper.rb b/app/helpers/detailmemos_helper.rb new file mode 100644 index 0000000..098faaf --- /dev/null +++ b/app/helpers/detailmemos_helper.rb @@ -0,0 +1,2 @@ +module DetailmemosHelper +end diff --git a/app/models/book.rb b/app/models/book.rb index 95c42dd..476d80b 100644 --- a/app/models/book.rb +++ b/app/models/book.rb @@ -1,5 +1,6 @@ # encoding: UTF-8 class Book < ActiveRecord::Base + has_many :detailmemos attr_accessible :memo, :purchased_on, :title validates :title, :presence => true diff --git a/app/models/detailmemo.rb b/app/models/detailmemo.rb new file mode 100644 index 0000000..be88f00 --- /dev/null +++ b/app/models/detailmemo.rb @@ -0,0 +1,4 @@ +class Detailmemo < ActiveRecord::Base + validates :memo, :length => { :maximum => 100} + attr_accessible :book_id, :memo +end diff --git a/app/views/books/show.html.erb b/app/views/books/show.html.erb index 23005ab..bd7a1cc 100644 --- a/app/views/books/show.html.erb +++ b/app/views/books/show.html.erb @@ -9,12 +9,24 @@ Memo: <%= @book.memo %>

+<% if @memos %> + <% for memo in @memos %> +

+ <%= memo.memo %> + <%= link_to 'Delete', memo,:controller => 'detailmemos', :action => 'destroy', confirm: 'Are you sure?', :method => :delete %> + +

+ <% end %> +<% end %>

Purchased on: <%= @book.purchased_on %>

- + +<%= link_to('Add Memo', :controller => 'detailmemos', :action => 'new', + :bookid => @book) %> + <%= link_to 'Edit', edit_book_path(@book) %> | <%= link_to 'Back', books_path %> diff --git a/app/views/detailmemos/_form.html.erb b/app/views/detailmemos/_form.html.erb new file mode 100644 index 0000000..d78060e --- /dev/null +++ b/app/views/detailmemos/_form.html.erb @@ -0,0 +1,24 @@ +<%= form_for(@detailmemo) do |f| %> + <% if @detailmemo.errors.any? %> +
+

<%= pluralize(@detailmemo.errors.count, "error") %> prohibited this detailmemo from being saved:

+ + +
+ <% end %> + +
+ <%= f.hidden_field(:book_id,:value => params[:bookid])%> +
+
+ <%= f.label :memo %>
+ <%= f.text_area :memo %> +
+
+ <%= f.submit %> +
+<% end %> diff --git a/app/views/detailmemos/edit.html.erb b/app/views/detailmemos/edit.html.erb new file mode 100644 index 0000000..a1d64b2 --- /dev/null +++ b/app/views/detailmemos/edit.html.erb @@ -0,0 +1,5 @@ +

Editing detailmemo

+ +<%= render 'form' %> + +<%= link_to 'Back', book_path %> diff --git a/app/views/detailmemos/new.html.erb b/app/views/detailmemos/new.html.erb new file mode 100644 index 0000000..1b61be7 --- /dev/null +++ b/app/views/detailmemos/new.html.erb @@ -0,0 +1,5 @@ +

New detailmemo

+ +<%= render 'form' %> + +<%= link_to 'Back', books_path %> diff --git a/app/views/detailmemos/show.html.erb b/app/views/detailmemos/show.html.erb new file mode 100644 index 0000000..2cc5eb5 --- /dev/null +++ b/app/views/detailmemos/show.html.erb @@ -0,0 +1,15 @@ +

<%= notice %>

+ +

+ Book: + <%= @detailmemo.book_id %> +

+ +

+ Memo: + <%= @detailmemo.memo %> +

+ + +<%= link_to 'Edit', edit_detailmemo_path(@detailmemo) %> | +<%= link_to 'Back', books_path %> diff --git a/config/routes.rb b/config/routes.rb index f3d38ab..4568152 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,7 @@ BookMemo2::Application.routes.draw do - resources :books + resources :detailmemos + resources :books # The priority is based upon order of creation: # first created -> highest priority. diff --git a/db/migrate/20120614162548_create_detailmemos.rb b/db/migrate/20120614162548_create_detailmemos.rb new file mode 100644 index 0000000..2c747d6 --- /dev/null +++ b/db/migrate/20120614162548_create_detailmemos.rb @@ -0,0 +1,10 @@ +class CreateDetailmemos < ActiveRecord::Migration + def change + create_table :detailmemos do |t| + t.integer :book_id + t.text :memo + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 5fc61c2..63e5926 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120526050801) do +ActiveRecord::Schema.define(:version => 20120614162548) do create_table "books", :force => true do |t| t.string "title" @@ -21,4 +21,11 @@ t.datetime "updated_at", :null => false end + create_table "detailmemos", :force => true do |t| + t.integer "book_id" + t.text "memo" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + end diff --git a/spec/controllers/detailmemos_controller_spec.rb b/spec/controllers/detailmemos_controller_spec.rb new file mode 100644 index 0000000..5bcda58 --- /dev/null +++ b/spec/controllers/detailmemos_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 DetailmemosController do + + # This should return the minimal set of attributes required to create a valid + # Detailmemo. As you add validations to Detailmemo, 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 + # DetailmemosController. Be sure to keep this updated too. + def valid_session + {} + end + + describe "GET new" do + it "assigns a new detailmemo as @detailmemo" do + get :new, {}, valid_session + assigns(:detailmemo).should be_a_new(Detailmemo) + end + end + + describe "POST create" do + describe "with valid params" do + it "creates a new Detailmemo" do + expect { + post :create, {:detailmemo => valid_attributes}, valid_session + }.to change(Detailmemo, :count).by(1) + end + + it "assigns a newly created detailmemo as @detailmemo" do + post :create, {:detailmemo => valid_attributes}, valid_session + assigns(:detailmemo).should be_a(Detailmemo) + assigns(:detailmemo).should be_persisted + end + + it "redirects to the created detailmemo" do + post :create, {:detailmemo => valid_attributes}, valid_session + response.should redirect_to(Book) + end + end + + describe "with invalid params" do + it "assigns a newly created but unsaved detailmemo as @detailmemo" do + # Trigger the behavior that occurs when invalid params are submitted + Detailmemo.any_instance.stub(:save).and_return(false) + post :create, {:detailmemo => {}}, valid_session + assigns(:detailmemo).should be_a_new(Detailmemo) + end + + it "re-renders the 'new' template" do + # Trigger the behavior that occurs when invalid params are submitted + Detailmemo.any_instance.stub(:save).and_return(false) + post :create, {:detailmemo => {}}, valid_session + response.should render_template("new") + end + end + end + + describe "DELETE destroy" do + it "destroys the requested detailmemo" do + detailmemo = Detailmemo.create! valid_attributes + expect { + delete :destroy, {:id => detailmemo.to_param}, valid_session + }.to change(Detailmemo, :count).by(-1) + end + + it "redirects to the detailmemos list" do + detailmemo = Detailmemo.create! valid_attributes + delete :destroy, {:id => detailmemo.to_param}, valid_session + response.should redirect_to(book_path(1)) + end + end + +end diff --git a/spec/factories/detailmemos.rb b/spec/factories/detailmemos.rb new file mode 100644 index 0000000..baea5e9 --- /dev/null +++ b/spec/factories/detailmemos.rb @@ -0,0 +1,8 @@ +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :detailmemo do + book_id 1 + sequence(:memo) { |n| "MyText_#{n}" } + end +end diff --git a/spec/helpers/detailmemos_helper_spec.rb b/spec/helpers/detailmemos_helper_spec.rb new file mode 100644 index 0000000..8d162bb --- /dev/null +++ b/spec/helpers/detailmemos_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the DetailmemosHelper. For example: +# +# describe DetailmemosHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# helper.concat_strings("this","that").should == "this that" +# end +# end +# end +describe DetailmemosHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/.detailmemo_spec.rb.swp b/spec/models/.detailmemo_spec.rb.swp new file mode 100644 index 0000000..497d532 Binary files /dev/null and b/spec/models/.detailmemo_spec.rb.swp differ diff --git a/spec/models/detailmemo_spec.rb b/spec/models/detailmemo_spec.rb new file mode 100644 index 0000000..d617f40 --- /dev/null +++ b/spec/models/detailmemo_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe Detailmemo do + pending "add some examples to (or delete) #{__FILE__}" + context "under 100" do + memo = "a" * 100 + subject { Detailmemo.new(:memo => memo).valid?} + it { should be_true} + end + + context "under 100" do + memo = "a" * 101 + subject { Detailmemo.new(:memo => memo).valid?} + it { should be_false} + end +end diff --git a/spec/requests/detailmemos_spec.rb b/spec/requests/detailmemos_spec.rb new file mode 100644 index 0000000..7c7d797 --- /dev/null +++ b/spec/requests/detailmemos_spec.rb @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +require 'spec_helper' + +describe "Detailmemos" do + + describe '/books/:book_id/' do + let!(:book){ FactoryGirl.create :book } + let!(:detailmemo){ FactoryGirl.create :detailmemo } + subject { page } + + before { visit "/books/#{book.id}" } + it "show Add Memo link" do + page.should have_css("#add_memo",:text => "Add Memo") + end + + context "write memo1" do + let(:memo_data){ 'memo test 1' } + + before do + click_on 'Add Memo' + fill_in "detailmemo_memo", with: memo_data + click_on 'Create Detailmemo' + end + + it "page is moved" do + current_path.should == books_path + end + + it "memo1 is exist" do + visit "/books/#{book.id}" + page.should have_content(memo_data) + end + end + context "write memo2" do + let(:memo_data){ 'memo test 2' } + + before do + click_on 'Add Memo' + fill_in "detailmemo_memo", with: memo_data + click_on 'Create Detailmemo' + end + + it "page is moved" do + current_path.should == books_path + end + + it "memo2 is exist" do + visit "/books/#{book.id}" + page.should have_content(memo_data) + end + end + end +end diff --git a/spec/routing/detailmemos_routing_spec.rb b/spec/routing/detailmemos_routing_spec.rb new file mode 100644 index 0000000..a055df6 --- /dev/null +++ b/spec/routing/detailmemos_routing_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" + +describe DetailmemosController do + describe "routing" do + + it "routes to #index" do + get("/detailmemos").should route_to("detailmemos#index") + end + + it "routes to #new" do + get("/detailmemos/new").should route_to("detailmemos#new") + end + + it "routes to #show" do + get("/detailmemos/1").should route_to("detailmemos#show", :id => "1") + end + + it "routes to #edit" do + get("/detailmemos/1/edit").should route_to("detailmemos#edit", :id => "1") + end + + it "routes to #create" do + post("/detailmemos").should route_to("detailmemos#create") + end + + it "routes to #update" do + put("/detailmemos/1").should route_to("detailmemos#update", :id => "1") + end + + it "routes to #destroy" do + delete("/detailmemos/1").should route_to("detailmemos#destroy", :id => "1") + end + + end +end diff --git a/spec/views/detailmemos/new.html.erb_spec.rb b/spec/views/detailmemos/new.html.erb_spec.rb new file mode 100644 index 0000000..58d9478 --- /dev/null +++ b/spec/views/detailmemos/new.html.erb_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe "detailmemos/new" do + before(:each) do + assign(:detailmemo, stub_model(Detailmemo, + :book_id => 1, + :memo => "MyText" + ).as_new_record) + end + + it "renders new detailmemo form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form", :action => detailmemos_path, :method => "post" do + assert_select "input#detailmemo_book_id", :name => "detailmemo[book_id]" + assert_select "textarea#detailmemo_memo", :name => "detailmemo[memo]" + end + end +end