2016年4月28日 星期四

Cloud9-RoR-Shopping Cart 購物車 Part.2

參考影片-第三篇:https://www.youtube.com/watch?v=Wo2-PcGD4mE
這篇都在教設計版面,個人覺得可看可不看。
參考影片-第四篇:https://youtu.be/WRVwfVUaj_Y?t=4m10s
購物車code的部份。(為什麼我會設定4分10秒開始播放呢?因為前面都在講唔欸某欸…)

第三篇都在說明版面的設計(html、css),第四篇是購物車的部份,所以決定把三、四篇寫在一起,才不會太空虛…

以下是第三篇的檔案內容,其他就不再多加贅述了哦!如果你心裡有其他想要的設計,那就不需要照著做,我是想照著他的步驟有了基本設計後再來做調整修改,對我來說比較順手。

views/layouts/application.hrml.erb
<!DOCTYPE html>
<html>
<head>
  <title>Workspace</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>
<nav id="nav">
  <div id="page_nav">
    <%= link_to('首頁', root_path) %>
    <%= link_to('產品', products_path) %>
    <%= link_to('關於我們', page_about_path) %>
    <%= link_to('問與答', page_faqs_path) %>
    <%= link_to('聯絡我們', page_contact_path) %>
  </div>
  
  <div id="sign_in">
    <% if user_signed_in? %>
      Signed in as <%= current_user.email %>. Not you?
      <%= link_to('登出', destroy_user_session_path, :method => :delete) %> |
      <%= link_to('修改密碼', edit_registration_path(:user)) %>
    <% else %>
      <%= link_to('註冊', new_registration_path(:user)) %> |
      <%= link_to('登入', new_session_path(:user)) %>
    <% end %>
  </div>
</nav>

<div id="main_wrap">
  <% if notice %>
    <p class="alert alert-success"><%= notice %></p>
  <% end %>
  <% if alert %>
    <p class="alert alert-danger"><%= alert %></p>
  <% end %>
  
  <%= yield %>
</div>
</body>
</html>

app/assets/stylesheets/application.css
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
 * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any styles
 * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
 * file per style scope.
 *
 *= require_tree .
 *= require_self
 */

*{
    margin: 0;
    padding: 0;
}

#nav{
    width: 100%;
    height:40px;
    background: #000;
    float: left;
}

#page_nav a, #sign_in a {
    line-height: 40px;
    color: #FFF;
    padding: 0 20px 0 20px;
    text-decoration: none;
}

#page_nav {
    margin:  0 0 0 5%;
    float:  left;
}

#sign_in{
    float: right;
    margin:  0 5% 0 0;
}

#main_wrap {
    width: 90%;
    float: left;
    margin: 20px 5% 0 5%;
    
}
----------------------------------------------------

第四篇,routes.rb購物車的address設定,編輯成下列內容
  get '/cart' => 'cart#index'
  get '/cart/clear' => 'cart#clearCart'
  get '/cart/:id' => 'cart#add'
*get '{網址}' => '{controller}#{action}'

文章有提到本來要把cart的controller檔案內容放到影片的說明,不過沒放,以下就是cart_controller.rb內容,拿去用唄!
class CartController < ApplicationController
  
  def add
    id = params[:id]
    #if the cart has already been created, use the existing cart else create a new cart
    if session[:cart] then
      cart = session[:cart]
    else
      session[:cart] = {}
      cart = session[:cart]
    end
    #if the product has already been added to the cart, increment the value else set the value to 1
    if cart[id] then
      cart[id] = cart[id] + 1
    else
      cart[id] = 1
    end
    redirect_to :action => :index
  end
  
  def clearCart
    session[:cart] = nil
    redirect_to :action => :index
  end
  
  def index
    #if there is a cart , pass it to the page for display else pass an empty value
    if session[:cart] then
      @cart = session[:cart]
    else
      @cart = {}
    end
  end
  
end

看完後是不是有空虛、寂寞、覺得冷的情形呢…

Cloud9-RoR-實用指令

因為我太愛忘記一些常用到的指令了,所以寫一篇幾乎每次撰寫code時都會用到的指令大全…

執行網站
$ rails s -b $IP -p $PORT

mysql重啟
$ mysql-ctl restart

建立一個controller檔
$ rails g controller controller_file_name

建立一個migration檔
$ rails g migration migration_file_name

建立/更新資料表結構
$ bin/rake db:migrate

查詢routes
$ rake routes

這篇應該會更新一輩子。

2016年4月27日 星期三

Cloud9-RoR-Shopping Cart 購物車 Part.1

參考影片-第一篇:https://www.youtube.com/watch?v=4jVOnrUvCQQ
主要是在介紹網站建置好的模樣,以及網站功能,可以先看看哦!
參考影片-第二篇:https://www.youtube.com/watch?v=4OPdxPawXrw
開始寫code嘍!不過如果你是用Cloud9,前面的一些步驟可以不用做,像是專案的建置等等,而且本影片的會員功能也是使用devise套件,可以到這裡看看,我有稍做介紹哦。(mail驗證的部份請先不要打開)

先寫寫第二篇的步驟吧!

如果你是開一個新專案,請先執行下面的步驟。
$ bundle install
$ mysql-ctl restart

Mysql database的設定檔請參考這裡

建立page controller及其view檔
$ rails g controller page home about faqs contact

打開routers.rb檔,把page#home指定為首頁
root 'page#home'
page 'page/home'   //記得刪掉哦

建立product的controller
$ rails g controller product title:string description:text image_url:string price:integer category:string subcategory:string

建立product資料表
$ bin/rake db:migrate

建立cart controller
$ rails g controller cart index

接著就是使用devise套件嘍,請參考這裡,當然也可以照著影片的步驟做,我就不再做重複的解說了。

在建立好devise之後,有個步驟會修改layouts/application.html.erb檔,這是我的application.html.erb最後的長相。
<!DOCTYPE html>
<html>
<head>
  <title>Workspace</title>
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>
<% if user_signed_in? %>
    Signed in as <%= current_user.email %>. Not you?
    <%= link_to('登出', destroy_user_session_path, :method => :delete) %> |
    <%= link_to('修改密碼', edit_registration_path(:user)) %>
<% else %>
    <%= link_to('註冊', new_registration_path(:user)) %> |
    <%= link_to('登入', new_session_path(:user)) %>
<% end %>

<br/><br/>
<%= link_to('首頁', root_path) %>
<%= link_to('關於我們', page_about_path) %>
<%= link_to('問與答', page_faqs_path) %>
<%= link_to('聯絡我們', page_contact_path) %>
      
<% if notice %>
  <p class="alert alert-success"><%= notice %></p>
<% end %>
<% if alert %>
  <p class="alert alert-danger"><%= alert %></p>
<% end %>

<%= yield %>

</body>
</html>

第二篇影片也到此結束了。這篇像在寫回憶錄,我是做完整個步驟了才來補寫日誌,所以不確定是不是有遺漏的地方,我想應該是沒有。影片中沒有做到database的設定,如果你是要用mysql就一定要補做我上面提到的database設定檔,否則cloud9的預設db是sqlite哦!

2016年4月7日 星期四

Cloud9-RoR-jQuery套版

參考文章(1):http://openhome.cc/Gossip/Rails/Layout.html
參考文章(2):http://openhome.cc/Gossip/Rails/Assets.html
輔助文章(1):https://ihower.tw/rails4/assets-pipeline.html
輔助文章(2):http://guides.rubyonrails.org/asset_pipeline.html
輔助文章(3):http://api.rubyonrails.org/v3.0.9/classes/ActionView/Helpers/AssetTagHelper.html
輔助文章(2)-簡中:http://guides.ruby-china.org/asset_pipeline.html

因為我目前的打算是每頁都有屬於自己的版面功能,所以這篇是介紹怎麼替單獨的頁面套上jQuery版型。很多範例都是加在app/assets裡,但這樣會套用到所有的頁面,跟我要的不一樣,結果又花了好多時間研究…

在rails中,可以放js及css檔的地方其實有三個,輔助文章(1)裡面有做仔細的說明,因為我是要使用jQuery,所以放在vendor/assets裡。

在目錄處找到vendor/assets,將jQuery中的js檔及css檔分別放入javascripts和stylesheets folder中,不過為預防日後還會使用到不同的jQuery會混淆不清,所以我們先在javascripts和stylesheets的folder底下新增一個這次要使用的jQuery folder名稱,名稱建議取相同的,才知道是同一組jQuery的檔案,然後新增兩個檔案。

新增一個同樣名稱的js檔放在vendor/assets/javascripts,例如myjQuery.js
//= require_tree .

新增一個同樣名稱的css檔放在vendor/assets/stylesheets,例如myjQuery.css
 /*
 = require_tree .
*/

如果jQuery會使用到圖檔,請在vendor/assets下方建立一個images folder,一樣在images底下新增同名的folder,把會使用到的圖片上傳至此folder中。css檔裡的圖檔連結請一定要照規定寫,否則會找不到圖片哦!

我是將會使用到圖片的該隻css檔,副檔改為scss,只要有image連結的部份都一律改為「image-url」(括弧內一定要加雙引號,否則會出錯)
background-image: image-url("myjQuery/rails.png")

打開這次要套用jQuery的html.erb檔,我習慣將套件放在最下方
.
.
.
<!-- css //-->
<%= stylesheet_link_tag 'myjQuery' %>

<!-- jquery //-->
<%= javascript_include_tag 'myjQuery' %>

編輯config/initializers/assets.rb(我是使用rails4.2,config.assets.precompile已被移入assets.rb裡了,寫在config/environments/production.rb裡沒用哦!)
Rails.application.config.assets.precompile += %w( myjQuery.js myjQuery.css )
Rails.application.config.assets.precompile += %w( *.png *gif *.jpg )
註:第二行是我的css裡會用到的圖檔類型,如果你有用到其他更多類型的檔案(不一定是圖檔),可以自行加上*.你會用的檔案副檔名。

這樣就套版完成嘍!

2016年4月5日 星期二

Cloud9-RoR-Action Mailer

參考文章:https://ihower.tw/rails4/actionmailer.html
參考文章:http://rails.ruby.tw/action_mailer_basics.html
輔助文章:http://rails.ruby.tw/testing.html#testing-your-mailers
輔助文章:http://stackoverflow.com/questions/26224080/cloud9-with-ruby-on-rails-doesnt-send-emails

當現有管理者新增一位管理者時,我希望對方能收到通知信,所以本篇要介紹怎麼建立一個mailer。

*Mailer 和 Controller 非常類似。方法都叫做“動作”,用 View 來組織信件內容。但 Controller 是產生 HTML 回給客戶端;然而 Mailer 則是建立透過 email 寄出的信件(message)。

在指令處下
$ bin/rails generate mailer UserMailer

編輯app/mailers/application_mailer.rb,我打算使用gmail系統,所以本篇都會使用gmail當範例(xxx請改成自己的gmail帳號)
class ApplicationMailer < ActionMailer::Base
  default from: "xxx@gmail.com"
  layout 'mailer'
end

編輯app/mailers/user_mailer.rb(myweb.com記得改成自己的網址)
class UserMailer < ApplicationMailer
  default :from => "xxx@gmail.com"
  def admin_create(user)
    @url = "https://myweb.com/"
    @user = user
    mail( to: @user.email, subject: "Welcome to myweb")
  end
end

新增信件內容為html格式的檔案,admin_email.html.erb在app/views/user_mailer/底下
<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Welcome to myweb.com, <%= @user.name %></h1>
    <p>
      You have successfully signed up to myweb.com,
      your username is: <%= @user.login %>.<br>
    </p>
    <p>
      To login to the site, just follow this link: <%= @url %>.
    </p>
    <p>Thanks for joining and have a great day!</p>
  </body>
</html>

在同個目錄下再新增一個文字格式的檔案admin_email.text.erb
Welcome to myweb.com, <%= @user.name %>
===============================================
 
You have successfully signed up to myweb.com
your username is: <%= @user.login %>.
 
To login to the site, just follow this link: <%= @url %>.
 
Thanks for joining and have a great day!

執行指令建立一個users_controller.rb
$ rails g controller users

開啟並編輯users_controller.rb
class UsersController < ApplicationController
  def create
    @user = User.new(params[:user])
 
    respond_to do |format|
      if @user.save
        # Tell the UserMailer to send a welcome email after save
        UserMailer.welcome_email(@user).deliver_later
 
        format.html { redirect_to(@user, notice: 'User was successfully created.') }
        format.json { render json: @user, status: :created, location: @user }
      else
        format.html { render action: 'new' }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end
end

增加gmail smtp的設定,開啟config/environments/development.rb檔並編輯
  # Mail SMTP for gmail
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.default_url_options = { host: "https://myweb.com" }
  config.action_mailer.smtp_settings = config_for(:email).symbolize_keys

在config下建立一個新檔名為email.yml
development:
  address: 'smtp.gmail.com'
  port: '2587'
  domain: 'gmail.com'
  user_name: 'xxx@gmail.com'
  password: '<gmailpassword>'
  authentication: 'plain'
  enable_starttls_auto: true
  
production:
  address: 'smtp.gmail.com'
  port: '2587'
  domain: 'gmail.com'
  user_name: 'xxx@gmail.com'
  password: '<gmailpassword>'
  authentication: 'plain'
  enable_starttls_auto: true
  
test:
  address: 'smtp.gmail.com'
  port: '2587'
  domain: 'gmail.com'
  user_name: 'xxx@gmail.com'
  password: '<gmailpassword>'
  authentication: 'plain'
  enable_starttls_auto: true

試寄了一個信箱後會看到以下訊息
Sent mail to xxx@gmail.com (30004.4ms)

不過實際上並沒有收到任何mail...這問題卡了我一、兩個星期了,還是找不到正確的解決辦法,所以決定先到此為止,繼續下一個部份。