保华的Rails学习笔记

暂未记住的知识点汇总

做了许多遍,有些知识点还是默写不出来,为了能让自己记住,就贴在这里,时不时的看一眼,时间长了,相信总是能熟练快速的写出来。
会一直更新内容,自己记住的,就删除,记不住的就先丢过来,继续前行,老师说要冲进度,其实非常有道理

1、bootstrap中关于alert的代码

app/views/common/_flashes.html.erb

<% if flash.any? %>
  <% user_facing_flashes.each do |key, value| %>
    <div class="alert alert-dismissable alert-<%= flash_class(key) %>">
      <button class="close" data-dismiss="alert">×</button>
      <%= value %>
    </div>
  <% end %>
<% end %>
app/helpers/flashes_helper.rb

module FlashesHelper
  FLASH_CLASSES = { alert: "danger", notice: "success", warning: "warning"}.freeze

  def flash_class(key)
    FLASH_CLASSES.fetch key.to_sym, key
  end

  def user_facing_flashes
    flash.to_hash.slice "alert", "notice","warning" 
  end
end

2、rake routes

有些verb还是没记住,例如patch是哪个action的,这些先背下来,总会用上的

3、db/seed.rb的写法

db/seed.rb
puts "這個種子檔會自動建立一個admin帳號, 並且創建 10 個 public jobs, 以及10個hidden jobs"

create_account = User.create([email: 'example@gmail.com', password: '12345678', password_confirmation: '12345678', is_admin: 'true'])
puts "Admin account created."

create_jos = for i in 1..10 do
  Job.create!([title: "Job no.#{i}", description: "這是用種子建立的第 #{i} 個Public工作", wage_upper_bound: rand(50..99)*100, wage_lower_bound: rand(10..49)*100, is_hidden: "false"])
end
puts "10 Public jobs created."

create_jos = for i in 1..10 do
  Job.create!([title: "Job no.#{i+10}", description: "這是用種子建立的第 #{i+10} 個Hidden工作", wage_upper_bound: rand(50..99)*100, wage_lower_bound: rand(10..49)*100,is_hidden: "true"])
end
puts "10 Hidden jobs created."

4、在做simple_form_for表单的时候,如果不想用表单的原始名称,可以用label,例如f.input :wage_lower_bound, :label: "薪资下限“

<h1>Edit a job</h1>
<%= simple_form_for [:admin,@job] do |f| %>
  <%= f.input :title %>
  <%= f.input :description %>
  <%= f.input :wage_lower_bound, :label => "薪资下限" %>
  <%= f.input :wage_upper_bound, label: "薪资上限" %>
  <%= f.input :contact_email %>
  <%= f.submit "Submit" %>
<% end %>

注意两种写法都是可以的

5、薪资大于0的正确写法

validates :wage_lower_bound, numericality: { greater_than: 0}

app/models/job.rb

  validates :wage_upper_bound, presence: true
  validates :wage_lower_bound, presence: true
  validates :wage_lower_bound, numericality: { greater_than: 0}

6、被隐藏的文章应该在首页看不到的正确写法

def index
    @jobs = Job.where(is_hidden: false)
  end

或者

def index
    @jobs = Job.where(:is_hidden => false)
  end

注意:这两种写法都可以,但是false不能加引号,一加引号就执行不正确

7、安装 FontAwesome

各种围标在:http://fontawesome.io/icons/
1)在gem挂上 gem 'font-awesome-rails'
2)执行bundle install
3)修改 app/assets/stylesheets/application.scss
加入*= require font-awesome
也加入@import "font-awesome";
4)重开rails server
5)helper改为

app/helpers/jobs_helper.rb
  def render_job_status(job)
    if job.is_hidden
      content_tag(:span, "", :class => "fa fa-lock")
    else
      content_tag(:span, "", :class => "fa fa-globe")
    end
  end

要改变图标,改变class中fa fa-后边的即可,例如 fa fa-map、fa fa-map-pin

8、加分题中的实作hide与public

1)在controller中写hide与public这两个action

def publish
    @job = Job.find(params[:id])
    @job.publish!
    redirect_to :back
  end
  def hide
    @job = Job.find(params[:id])
    @job.hide!
    redirect_to :back
  end

2)在model中写hide!和public!

app/models/job.rb
class Job < ApplicationRecord
  def publish!
    self.is_hidden = false
    self.save
  end

  def hide!
    self.is_hidden = true
    self.save
  end
end  

3)写routes.rb文件,把public与hide的path添加进去

config/routes.rb
  namespace :admin do
    resources :jobs do
      member do
        post :publish
        post :hide
      end
    end
  end

4)在index.html.erb中,在edit/delete后边添加public或者hide按钮

<% if job.is_hidden %>

    <%= link_to("Publish", publish_admin_job_path(job) , :method => :post, :class => "btn btn-xs btn-default") %>
  <% else %>
    <%= link_to("Hide", hide_admin_job_path(job), :method => :post,  :class => "btn btn-xs btn-default") %>
  <% end %>

9、下拉菜单的实现代码(前端)

<div class="dropdown clearfix pull-right">
    <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenuDivider" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
      排序
        <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" aria-labelledby="dropdownMenuDivider">
        <li>
          <%= link_to("按照薪资下限排序", jobs_path(:order => "by_lower_bound")) %>
        </li>
        <li>
            <%= link_to("按照薪资上限排序", jobs_path(:order => "by_upper_bound")) %>

        </li>
        <li>
          <%= link_to("按照发表时间排序", jobs_path ) %>

        </li>
    </ul>
</div>

结构分析:1)总体是一个div代码 2)div代码中有一个button代码与一个ul代码,3)ul代码中有3个li代码

10、carrierwave的应用

1)、在gem挂上carrierwave
(1)gem 'carrierwave'
(2)终端执行bundle install
(3)重开rails s
2)、在resume上增加字段attachment
(1)rails g migration add_attachment_to_resume
(2)新产生的文件内容

class AddAttachmentToResume < ActiveRecord::Migration[5.0]
  def change
    add_column :resumes, :attachment, :string
  end
end

(3)rake db:migrate
3)挂上 Attachment Uploader 到 Resume 上
carrierwave 使用的是“Uploader”这个机制,因此呢,我们要

rails g uploader attachment
然后再修改 model,挂上去

app/models/resume.rb
class Resume < ApplicationRecord
  belongs_to :user
  belongs_to :job

  mount_uploader :attachment, AttachmentUploader

  validates :content, presence: true
end

然后修改

app/views/resumes/new.html.erb
<%= simple_form_for [@job, @resume] do |f| %>
  <%= f.input :content %>
  <%= f.input :attachment %>

  <%= f.submit "送出" %>
<% end %>

4)修改 resume_params

app/controllers/resumes_controller.rb
  def resume_params
    params.require(:resume).permit(:content, :attachment)
  end

11、添加搜索框

1)在index里边添加代码

def index
    jobs = Job.all
    if params[:search]
      @jobs = Job.published.search(params[:search])
    elsif
    @jobs = case params[:order]
            when 'by_lower_bound'
              Job.published.order('wage_lower_bound DESC')
            when 'by_upper_bound'
              Job.published.order('wage_upper_bound DESC')
            else
              Job.published.recent
            end
    end
  end

2)在model里边添加代码

  def self.search(search)
      where("title LIKE ? OR description LIKE ? ", "%#{search}%","%#{search}%")
  end

3)在view页面添加代码,这里添加到jobs首页

<%= form_tag(jobs_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search jobs" %>
<%= submit_tag "Search" %>
<% end %>

12 link_to do的用法

出自:http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html

<%= link_to(@profile) do %>
  <strong><%= @profile.name %></strong> -- <span>Check it out!</span>
<% end %>
# => <a href="/profiles/1">
       <strong>David</strong> -- <span>Check it out!</span>
     </a>

教材中的用法为:

<div class="row">
  <% @products.each do |product| %>
    <div class="col-xs-6 col-md-3">
      <%= link_to product_path(product) do %>
        <% if product.image.present? %>
          <%= image_tag(product.image.thumb.url, class: "thumbnail") %>
        <% else %>
          <%= image_tag("http://placehold.it/200x200&text=No Pic", class: "thumbnail") %>
        <% end %>
      <% end %>
      <%= product.title %> ¥ <%= product.price %>
    </div>
  <% end %>
</div>

link_to do的用法,虽然不是很懂,但是通过查资料,大概明白了它有用法,不理解的,还是先背下来怎么用吧,以后还会遇到的

2/21学到的知识点

今天把陈俊鸿同学写的CSS系列文章学习了一遍

get到的知识点:
1)如果三个元素(block)需要在一行显示,那么这三个元素要加float: left属性,而且它们外边要加一个元素,把这三个包起来(这样可以通过外边的元素来调整里边这3个元素的总体位置、高度、宽度等)
2)当一个元素的height与line-height一样时,里边的内容是垂直居中的
3)em与px的区别:px是绝对值,而em是相对值,它是相对于它外边的元素,例如如果外边的元素font-size:16px,那么1em就是16px,2em就是32px

4)当table增加了新的栏目后,之前提交的记录这个字段值为nil,这时候再去调用,会出问题,解决方法,在rails c中删除这些字段值为nil的记录

这几天学习计划有点乱了,新课程还没开始做,要加油了

2/19 ORID日记

Objective

关于今天的课程, 你记得什么?
完成了什么?

继续魔改,网站改版了,样式改了,今天JS的问题基本困惑了好久,在本地运行是好的,一上传到heroku,不单下拉菜单不起作用,而且加入购物车也不起作用,后来在slack上边提问,终于解决了,把出错的那一段JS删除就解决了

Reflective

你要如何形容今天的情绪
今天的高峰是什么?

今天基本上比较郁闷,因为JS的问题,找了许多解决方法,到论坛上边,试了大家的方法也不行,所以心情有些诅丧,不过最终还是解决了

今天的低潮是什么?

当JS问题没解决时,比较诅丧

Interpretive

我们今天学到了什么?
今天一个重要的领悟是什么?

一个问题如果困惑太久了,就去请教别人,不要浪费太长时间

Decisional

我们会如何用一句话形容今天的工作
进步中

有哪些工作需要明天继续努力?
继续完善魔改

2/16 ORID日志

Objective

关于今天的课程, 你记得什么?
完成了什么?
这几天一直在魔改,日记也没好好写,以后还是要尽量写,第一版参赛作品上线,虽然还是不满意,但是还是先放上去吧,边学边改,参赛其实是一个很好的提取练习,很多想到的功能,教程上并没有,于是就去谷歌,去问同学,这与做真实项目的场景类似,而且是参赛,所以兴致都挺高,学习效率大幅上升
作品已完成的功能有:
1)搜索
2)增加分类页,首页可以调取分类页的一部分内容
3)修改了网站的标题,每个页面都有不一样的标题,这样更符号真实的购物网站
4)修改了注册登录页面
5)user增加了user_name栏目,在登录后,显示用户名代替之前的邮箱显示
5)AWS的应用

Reflective

你要如何形容今天的情绪
今天的高峰是什么?

情绪基本是高涨的,想到的功能做出来了,还是蛮开心,也蛮有成就感的,很多CSS写法,也是这几天才实践过程中才明白的,像老师说的那样,CSS就是要多用,在用的过程中熟练、学会

今天的低潮是什么?
没什么低潮

Interpretive

我们今天学到了什么?
今天一个重要的领悟是什么?

学到了case语句在view页面中的应用方法
content_for与field的配合使用,可以修改默认的标题
params参数的应用方法

以后学到的知识点,尽量要记起来,前几天对一个插件很熟悉,但是今天想的时候,硬是想不起来要怎么用,看来,不要过度的自信自己的记忆力,能记的还是要记起来,尤其是一个比较零碎的知识点

Decisional

我们会如何用一句话形容今天的工作
进步中

有哪些工作需要明天继续努力?
练习本周课程

02/12 ORID

Objective

关于今天的课程, 你记得什么?
完成了什么?

购物第二周课程完成一遍

Reflective

你要如何形容今天的情绪
今天的高峰是什么?
购物课程这一遍,基本以提取练习为主,比前几遍明显能够记住的知识点多了,很多逻辑关系基本也理顺清楚了
感觉课程任务蛮重的,明天又有新课程放出来,而且还要准备参赛作品,想起来,感觉有些压力,因为时间真的太赶了,最近工作方面事情也多

今天的低潮是什么?
没什么低潮

Interpretive

我们今天学到了什么?
今天一个重要的领悟是什么?

当代码不懂的时候,尽量多练习吧,先把它记下来

Decisional

我们会如何用一句话形容今天的工作
进步中

有哪些工作需要明天继续努力?
开始新课程
开始准备参赛作品

02/10出错日记


这里把SecureRandom的S写成小写了



上边订单信息没有调出来

原因:


下边忘记写product_list.save了,上边用的是new,就需要用save保存好

02/10 ORID日志

完成了什么?记得什么?

JDstore完成一遍
昨天YY老师的直播课听了一遍(昨天网络太差,听不了,只能今天听回放)

如何形容今天的情绪?高峰是什么?低点是什么?

听了YY老师的直播回放后,感觉还挺兴奋,解决了好几个语法小问题,而且老师说不懂的时候,继续练习就好,看来目前购物车课程自己没搞懂,还是练习的遍数不够,明天继续练习
今天心情没有低点

今天学到了什么?重要的领悟是什么?

听了老师的直播回放后,弄清了一些语法问题
1)!在前边表示逻辑非,就是NOT,在后边就是要改变本身的状态,例如publish!,!=表示不等于
2)?表示回传值是true/false
3)debug小技巧,当提交表单没错误提示,而且页面没跳转,这时候,可以把.save改为.save!,这样出错的时候会报错
4)购物车的正确写法:cart = Cart.find_by(id:session[:cart_id],错误写法:cart = Cart.find(session[:cart_id])
5)find_by后边可以跟多个查询条件,例如find_by_name_and_email("xxx","xxx@xxx.com")注意写法
6)显示用户自己订单的方法可以用:

def show
    @order = current_user.orders.find(params[:id])
end

这是比较安全的写法,比之前的写法(先把所有订单调取出来,再用判断语句if来取出用户自己的订单)要安全许多,之前写法先调所有单出来,然后再调取用户自己下的单,在这个过程中,容易泄漏不是用户自己下的订单

至所以许多知识还不懂,那是因为自己练习的不够,还要多练习

如何用一句话形容今天的学习?

进步中,比第一、第二遍有了更多的理解

有哪些工作需要明天继续努力?

继续练习jdstore

2月9号YY老师直播课程部分知识点


当find的条件为多个的时候,可以像上边这样用,但是条件过多的时候,不要这样用,代码不容易维护,最多两个就可以

第二种写法,容易出现首页打不开的情况
find(2)如果没有id为2的记录会报错这个id找不到
find_by_id(2)时,如果没有2返回为nil

?与!


用了!,用改变自身的状态

网站访问者只能看到自己的订单两种写法

1、第一种实现方法


1)这段代码的功能,是实现当用户看不属于它的订单的时候,直接跳转到root首页
2)这段代码中,@order = Order.find(params[:id])是实现把所有订单都找出来,这样做有安全隐患
3)所以它的实现过程是先把所有订单都找出来,然后根据判断来决定是显示,还是跳转到首页

2、第二种实现方法


1)它的实现方法是只把current_user的订单找出来并展示,比第一种要安全(第一种先把所有订单找出来)
2)当用户查看不属于它的订单的时候,网站会报404错误(意思是网站中不存在这个页面)

综合比起来,第二种最安全,而且更高效(不用调所有订单)

form for do用法举例

While this is an increase in comfort it is far from perfect. If Person has many attributes to edit then we would be repeating the name of the edited object many times. What we want to do is somehow bind a form to a model object, which is exactly what form_for does.

Assume we have a controller for dealing with articles app/controllers/articles_controller.rb:

def new
  @article = Article.new
end

The corresponding view app/views/articles/new.html.erb using form_for looks like this:

<%= form_for @article, url: {action: "create"}, html: {class: "nifty_form"} do |f| %>
  <%= f.text_field :title %>
  <%= f.text_area :body, size: "60x12" %>
  <%= f.submit "Create" %>
<% end %>

There are a few things to note here:

@article is the actual object being edited.
There is a single hash of options. Routing options are passed in the :url hash, HTML options are passed in the :html hash. Also you can provide a :namespace option for your form to ensure uniqueness of id attributes on form elements. The namespace attribute will be prefixed with underscore on the generated HTML id.
The form_for method yields a form builder object (the f variable).
Methods to create form controls are called on the form builder object f.
The resulting HTML is:

<form accept-charset="UTF-8" action="/articles" method="post" class="nifty_form">
  <input id="article_title" name="article[title]" type="text" />
  <textarea id="article_body" name="article[body]" cols="60" rows="12"></textarea>
  <input name="commit" type="submit" value="Create" />
</form>

The name passed to form_for controls the key used in params to access the form's values. Here the name is article and so all the inputs have names of the form article[attribute_name]. Accordingly, in the create action params[:article] will be a hash with keys :title and :body. You can read more about the significance of input names in the parameter_names section.

The helper methods called on the form builder are identical to the model object helpers except that it is not necessary to specify which object is being edited since this is already managed by the form builder.

更多form for的用法请参考:http://guides.rubyonrails.org/form_helpers.html