2015年9月15日 星期二

Cloud9-RoR-關聯設計

參考文章:https://ihower.tw/rails4/activerecord.html

我的資料表關聯是這樣的


新增兩個model(原本的events在前面幾篇就建好了)
$ rails g model category cname:string status:boolean
$ rails g model event_category event_id:integer category_id:integer
$ bin/rake db:migrate

編輯app/models/event.rb
class Event < ActiveRecord::Base
  has_many :event_categories, ->{ order("category_id") }, :dependent => :delete_all
  has_many :categories, :through => :event_categories
end

編輯app/models/category.rb
class Category < ActiveRecord::Base
  has_many :event_categories, :dependent => :delete_all
  has_many :categories, :through => :event_categories
end

編輯app/models/event_category.rb
class EventCategory < ActiveRecord::Base
  belongs_to :event
  belongs_to :category
end

如此一來,三個資料表就關聯起來了。

2015年9月14日 星期一

Cloud9-RoR-Can't connect to MySQL server...

每次只要重新開啟專案,似乎都會出現無法連線到MySQL的錯誤
rake aborted!
Mysql2::Error: Can't connect to MySQL server on '0.0.0.0' (111)
.
.
.

這時只要重啟MySQL就行了,在指令處下
$ mysql-ctl restart

這樣就能正常連線嘍!

2015年9月8日 星期二

Cloud9-RoR-RESTful應用

參考文章:https://ihower.tw/rails4/restful.html

修改config/routes.rb,增加resources :events,
刪除match ':controller(/:action(/:id(.:format)))', :via => :all
resources :events
*在routes.rb裡面,越上面的路由規則越優先。

重要的表格:
Helper GET POST PATCH/PUT DELETE
event_path(@event) /events/1
show action
/events/1
update action
/events/1
destroy action
events_path /events
index action
/events
create action
edit_event_path(@event) /events/1/edit
edit action
new_event_path /events/new
new action
輸入下列指令可以看到目前的routes.rb有哪些規則
$ bin/rake routes

修改app/views/events/index.html.erb
<ul>
<% @events.each do |event| %>
  <li>
  <%= event.title %>
  <%= link_to "Show", event_path(event) %>
  <%= link_to 'Edit', edit_event_path(event) %>
  <%= button_to 'Delete', event_path(event), :method => :delete, :data => { :confirm => "Are you sure?" } %>
  </li>
<% end %>
</ul>
<%= link_to 'New Event', new_event_path %>
<%= paginate @events %>

修改app/views/events/new.html.erb
<p><%= @event.title %></p>
<table border="0">
  <tr>
    <td><%= @event.public_date %></td>
    <td><%= @event.author %></td>
  </tr>
</table>
<p><%= simple_format(@event.description) %></p>

<p><%= link_to 'Back to index', events_path %></p>

修改app/views/events/new.html.erb
<%= form_for @event, :url => events_path do |f| %>
    <%= render :partial => 'form', :locals => { :f => f } %>
    <%= f.submit "Create" %>
    <%= link_to 'Back to index', :controller => 'events', :action => 'index' %>
<% end %>

修改app/views/events/edit.html.erb
<%= form_for @event, :url => event_path(@event), :method => :patch do |f| %>
    <%= render :partial => 'form', :locals => { :f => f } %>
    <%= f.submit "Update" %>
    <%= link_to 'Back to index', :controller => 'events', :action => 'index' %>
<% end %>

修改app/controllers/events_controller.rb,要修改的部份如下,藍色是原來的code,紅色是改變後的code
  def create
    @event = Event.new(event_params)
    if @event.save
      #redirect_to :action => :index
      redirect_to events_url
    else
      render :action => :new
    end
    flash[:notice] = "event was successfully created"
  end
  
  def update
    #@event = Event.find(params[:id])
    if @event.update(event_params)
      #redirect_to :action => :show, :id => @event
      redirect_to event_url(@event)
    else
      render :action => :edit
    end
    flash[:notice] = "event was successfully updated"
  end
  
  def destroy
    #@event = Event.find(params[:id])
    @event.destroy
  
    #redirect_to :action => :index
    redirect_to events_url
    flash[:alert] = "event was successfully deleted"
  end 

文章出處還有介紹其他xml、json的運用,大家可以玩玩看,因為這邊用不到所以就不多述了。

Cloud9-RoR-打造自己的CRUD

參考文章:https://ihower.tw/rails4/basic.html

CRUD:對資料庫做Create、Read、Update、Delete操作。

想要一步一步了解的人,可以照著參考文章練習,我只記錄檔案最後的樣子,以及要下的指令。

這個單元要建立的是一個類似Blog的功能,參考文章較像後台的樣子,所以就把它當成後台的建置唄。

產生一個Model
$ rails g model event cnttype:integer title:string description:text author:string is_public:boolean  public_date:date share:integer like:integer

執行指令建立資料表
$ bin/rake db:migrate

因為我是記錄正式站的建立步驟,所以直接跳到「實做基本的CRUD應用程式」,不過練習時還是所有乖乖把所有步驟都完成滴。

在config/routes.rb最後插入一行,這樣就不用每一條路徑都要進到routes.rb設定了
  # ....
  match ':controller(/:action(/:id(.:format)))', :via => :all
end

執行以下指令
$ rails g controller events

編輯app/controllers/events_controller.rb,灰字的部份是原來就存在檔案中的,我們要貼上的是綠色的部份
class EventsController < ApplicationController
  before_action :set_event, :only => [ :show, :edit, :update, :destroy]
  def index
    #@events = Event.all
    @events = Event.page(params[:page]).per(5)
  end
  
  def new
    @event = Event.new
  end
  def create
    @event = Event.new(event_params)
    if @event.save
      redirect_to :action => :index
    else
      render :action => :new
    end
    flash[:notice] = "event was successfully created"
  end
  
  def show
    #@event = Event.find(params[:id])
    @page_title = @event.title
  end
  
  def edit
    #@event = Event.find(params[:id])
  end
  def update
    #@event = Event.find(params[:id])
    if @event.update(event_params)
      redirect_to :action => :show, :id => @event
    else
      render :action => :edit
    end
    flash[:notice] = "event was successfully updated"
  end
  
  def destroy
    #@event = Event.find(params[:id])
    @event.destroy
  
    redirect_to :action => :index
    flash[:alert] = "event was successfully deleted"
  end
  
  #private以下的所有方法都會變成private方法,所以記得放在檔案的最底下。
  private
  
  def event_params
    params.require(:event).permit(:cnttype, :description, :author, :is_public, :public_date)
  end
  
  def set_event
    @event = Event.find(params[:id])
  end
end

Event.all會抓出所有的資料,回傳一個陣列給實例變數(instance variables)指派給@events。在Rails會讓Action裡的實例變數(也就是有@開頭的變數)通通傳到View樣板裡面可以使用。這個Action預設使用的樣板是app/views/events/目錄下與Action同名的檔案。

在app/view/s/events新增一個index.html.erb的檔案,內容如下
<ul>
<% @events.each do |event| %>
  <li>
    <%= event.title %>
  <%= link_to 'Show', :controller => 'events', :action => 'show', :id => event %>
  <%= link_to 'Edit', :controller => 'events', :action => 'edit', :id => event %>
  <%= link_to 'Delete', :controller => 'events', :action => 'destroy', :id => event %>
  </li>
<% end %>
</ul>
<%= link_to 'New Event', :controller => 'events', :action => 'new' %>
<%= paginate @events %>

新增app/views/events/new.html.erb檔案,內容如下
<%= form_for @event, :url => { :controller => 'events', :action => 'create' } do |f| %>
    <%= render :partial => 'form', :locals => { :f => f } %>

    <%= f.submit "Create" %>
    <%= link_to 'Back to index', :controller => 'events', :action => 'index' %>
<% end %>

新增app/views/events/show.html.erb檔案,內容如下
<%= @event.title %>
<table border="0">
  <tr>
    <td><%= @event.public_date %></td>
    <td><%= @event.author %></td>
  </tr>
</table>
<%= simple_format(@event.description) %>

<p><%= link_to 'Back to index', :controller => 'events', :action => 'index' %></p>

新增app/views/events/edit.html.erb檔案,內容如下
<%= form_for @event, :url => { :controller => 'events', :action => 'update', :id => @event } do |f| %>
    <%= render :partial => 'form', :locals => { :f => f } %>
    <%= f.submit "Update" %>
    <%= link_to 'Back to index', :controller => 'events', :action => 'index' %>
<% end %>

修改app/views/layouts/application.html.erb檔案中的<title>
<title><%= @page_title || "Event application" %></title>
show頁面的title會顯示活動名稱。其他頁面因為沒有設定@page_title,就會是「Event application」。

因為new.html.erb和edit.html.erb的內容都相同,所以我們做個局部樣板(Partial Template),新增app/views/events/_form.html.erb檔案,內容如下
<div>
<%= f.label :title, "文章" %>
<%= f.text_field :title, size: "50" %>
</div>
<div>
<%= f.label :cnttype, "類別" %>
<%= f.select(:cnttype, [['公益計畫', 1], ['案例平台', 2]]) %>
</div>
<div>
<%= f.label :author, "作者/出處" %>
<%= f.text_field :author, size: "30" %>
</div>
<div>
<%= f.text_area :description, size: "60x20"  %>
</div>
<div>
<%= f.label :public_date, "公開日" %>
<%= f.date_field :public_date %>
</div>
<div>
<%= f.check_box :is_public %>
<%= f.label :is_public, "草稿" %>
</div>
<div>
<% if @event.errors.any? %>
      <ul>
      <% @event.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
<% end %>
</div>
http://guides.rubyonrails.org/form_helpers.html,各種form元件的寫法。

指令處安裝分頁元件
$ gem install kaminari

安裝完成後,在Gemfile檔加上兩行
# page kaminari
gem 'kaminari'
分頁就能使用了。

這樣就做出基本的讀取、新增、修改、刪除功能溜!