• #62 楼 @windwiny gitbook 对中文的支持一直都不好,我后面改一下字体,看能不能解决。

  • #53 楼 @douxiance 不清楚怎么排序的。 Gitbook 关注已经超过 40...求分享或转发,希望能够对更多人有帮助

  • #37 楼 @riskgod 新创建了微信群,欢迎各位加入。

  • Gitbook 上已经有 30 几个 star 了... 😄 😄

  • #10 楼 @roclv #14 楼 @heliang7 还有很多要修改的,我自己都不满意,暂时没有出版的打算~

  • #3 楼 @42thcoder 创建图书,一直失败,也没有报错信息。放弃~

  • #1 楼 @flemon joins 只是查询条件,并没有预加载的效果。

  • #13 楼 @small_fish__ #14 楼 @heliang7 #15 楼 @limkurn #16 楼 @yaocanwei 感谢支持...求分享或转发。

  • #5 楼 @huacnlee 还有 @bastengao 通过邮件反馈的错误,后面修改......感谢。

  • 应该是 pry 的问题,设置编码或字符没用。 有时候是查询出来的内容格式不对;或者,查询能正常显示,但输入的时候格式不对,然后直接崩溃。

    直接去掉 pry-rails 有时候又不方便,折中的办法,打开控制台: DISABLE_PRY_RAILS=1 rails console

  • 竟然没有移动 nopoint ...

  • 楼上两位的回答 + 1 另外可以在 Client 里 delegate :title, to: :program, prefix: false

  • v2ex 应该是又解封了...

  • 可以参考 Rails 对 I18n yml 文件是如何加载的。

    # 定义。这里的 paths 表示你要监视的文件或目录(所在的路径)。
    i18n_reloader = ActiveSupport::FileUpdateChecker.new(paths) do
      I18n.reload! # 监视内容有变化时,执行什么操作。
      # Rails.application.reload_routes!
    end
    
    ActionDispatch::Reloader.to_prepare do # to_prepare 的作用,可参考对应说明。
      # 调用。如果有更新,则执行操作
      i18n_reloader.execute_if_updated
    end
    
    # 调用。手动执行操作
    i18n_reloader.execute
    

    我们用的是 services/*.rb 和 services/views/ 文件、目录。供参考:

    if Rails.env.development?
      # .rb 文件
      lib_ruby_files = Dir.glob(Rails.root.join("app/services/**/*.{rb}"))
    
      lib_ruby_reloader ||= ActiveSupport::FileUpdateChecker.new(lib_ruby_files) do
        Rails.application.reload_routes!
        lib_ruby_files.each do |lib_file|
          silence_warnings { require_dependency(lib_file) }
        end
      end
    
      Rails.application.reloaders << lib_ruby_reloader
    
      ActionDispatch::Callbacks.to_prepare do
        lib_ruby_reloader.execute_if_updated
      end
    
      # .rabl 文件
    
      rabl_files = Dir.glob(Rails.root.join("app/services/views/v1/**/*.rabl"))
    
      lib_rabl_reloader = ActiveSupport::FileUpdateChecker.new(rabl_files){
        lib_ruby_reloader.execute
       }
    
      Rails.application.reloaders << lib_rabl_reloader
    
      ActionDispatch::Reloader.to_prepare {
        lib_rabl_reloader.execute_if_updated
      }
    end
    

    补充:config.autoload_paths 还是要配置的。

  • 新主题上线 at 2015年04月06日

    搜索框默认改为展开吧 ... 别外,Command + Enter 回帖不起作用... Chrome 41.0.2272.118 (64-bit)

  • 产生缘由?

    "inverse_of 困惑的起源并不是在实际使用中产生的",不是这样的:

    # Controller
    @user = User.first
    @topics = user.topics
    
    # View
    @topics.each do |topic|
      topic.user.username # 这行代码
    end
    

    上面这样的例子,很常见吧。(先不要纠结这里的写法) 如果没有使用 inverse_of 的话,上面输出用户名,每次都要查询一次数据库,找到 topic.user,而这个对象我们在之前已经取出来,在内存里了。(验证的话,你可以设置 inverse_of: false) 使用 inverse_of 后,你省略这样的查询。

    当然,使用它还有其它作用,你懂的。

    Guide 文档自身就描述不清(或说自相矛盾?)

    这里,我同意你的看法...不过可以借助 reflection,判断是否有必要添加 inverse_of,以及添加后是否会有效。

    ModelName.reflections.map do |key, value|
      p "#{key} inverse_of: #{value.has_inverse?}"
    end
    

    有的关联会自动推断 inverse_of,所以用不用其实效果一样。而有的关联加上参数后,不起作用,所以即使设置也没用。可以根据上述代码检测 ...

    回答你的部分疑问

    官方举的例子不恰当。

  • #28 楼 和楼主是什么关系 ... 😯

  • [广州] 招聘 Ruby 工程师 at 2015年03月23日

    欢迎投简历呀 ...

  • 针对示例代码,要重构的话,下面是我想到的一种解决办法:

    class OrdersController < ApplicationController
      def charge_execute
        @order = Order.find(params[:id])
        @order.total = params[:order][:total].to_f
    
        redirect_to :action => 'charge_more', :id => @order and return unless @order.total > 0
    
        # 1. init beanstream payment gateway
    
        # 2. init creditcard, options or pair values
    
        # 3. send payment info to gateway and deal with response
        response = gateway.purchase(@order.total_in_cents, @order.get_creditcard, @order.options)
    
        if response.success?
          @order.update_credit_card(response.authorization)
          flash[:notice] = "Extra money #{@order.total} has been charged"
        else
          flash[:notice] = "Error of processing charge: #{response.message}."
        end
        redirect_to :action => 'show', :id => @order and return
      end
    
      private
      # 1. init beanstream payment gateway
      # 放到其它地方也可以(比如:ApplicationController)
      def gateway
        ActiveMerchant::Billing::BeanstreamGateway.new(
          :login    => $BEAN_STREAM_ID,
          :user     => $BEAN_STREAM_LOGIN,
          :password => $BEAN_STREAM_PASSWD
        )
      end
    end
    
    class Order < ActiveRecord::Base
      # 2. init creditcard, options or pair values
      # 你可以换个更好的名字
      def options
        {
          :order_id => self.id,
          :billing_address => {
            :name     => "#{self.billing_first_name} #{self.billing_last_name}",
            :phone    => self.billing_phone,
            :address1 => self.billing_street_address,
            :address2 => self.billing_street_address_2,
            :city     => self.billing_city,
            :state    => self.get_state_code,
            :country  => self.get_country_code,
            :zip      => self.billing_zip
          },
          :email  => self.email,
          :ref1   => "#{$DOMAIN_NAME} Order"
        }
      end
    
      # 你可以换个更好的名字
      def update_credit_card(authorization)
        credit_card = self.credit_card
        credit_card.transaction_id = credit_card.transaction_id + ',' + authorization
        credit_card.save
      end
    end
    

    对比使用“Service Object”,上面的重构方法,更常见,也更容易理解。 但问题是:这里的 OrderChargeLogic 逻辑不好重用!

    举例: 我们要对外提供独立的 api . 我们要开发独立的 mobile 版本 . (别问我为什么 ...)

    这里的 OrdersController#charge_execute 不能直接重用 (像下面的 redirect_to, flash, render 和 gateway 我们用不到或不好用)。

      redirect_to :action => 'charge_more', :id => @order and return unless @order.total > 0
    
      # ...
      if response.success?
        # ...
        flash[:notice] = "Extra money #{@order.total} has been charged"
      else
        flash[:notice] = "Error of processing charge: #{response.message}."
      end
      redirect_to :action => 'show', :id => @order and return
    
    private
    
    def gateway
      # ...
    end
    

    封装成"Service Object"的话,则可以重用。不管其它代码怎么变,只要提供 order, amount 就行

    class Api < Sinatra::Base
      put '/v1/orders/:id' do
        # ...
        charge_logic = OrderChargeLogic.new(@order, @amount * 100)
        charge_logic.execute
    
        # ...
      end
    end
    

    一,有没有必要使用 Service Object

    引人 service 层之后,可以带来很多好处:

    Controller 更容易测试。 业务逻辑从 Controller 中剥离,更容易独立测试。 业务与框架低耦合。 让 Controller 更 slim。

    但,我个人是觉得上面的重构方式更直观、容易理解; 使用 Service Object 的话,反而让简单的事变得复杂了。创建单独的 class OrderChargeLogic,新增一个类和多个方法,增加成本

    这里关键是:有没有必要?

    二,它的职责是什么?

    Service Object 封装了每一个业务流程。它负责组织应用领域模型(Model)之间的交互,并且不依赖于框架(Controller 层)

    上面举例里,就包括了所有: init_beanstream_payment_gateway init_creditcard_options send_payment_info_to_gateway log_credit_card_transaction

    也是一团麻,怎么保证 OrderChargeLogic 这个 class 自身的“单一职责”。


    @novtopro 已经更新

  • [广州] 招聘 Ruby 工程师 at 2015年03月20日

    炮哥又招人啦。想换工作的赶紧投简历过来 ... 😆

  • 估计是没有安装 mysql

    另外, bundle install 已经习惯性的改为 bundle -V

    rails new project 新生成的项目,也可以先把 Gemfile 里的 source 'https://rubygems.org' 改为 source 'http://rubygems.org'

  • 我不是。计算机科学与技术 ...

  • 我喜欢酱紫的 Hash at 2015年03月11日

    注意:英文的逗号后面不加空格,不会那么好看,比如本回复。

  • 'Destroy' 是第一个参数 article_path(article) 第二个参数

    method: :delete, data: { confirm: 'Are you sure?'} 对应第三个参数,外面省略了大括号而矣。外号:祼哈希

  • 关于 Rails 片段缓存的问题 at 2015年02月26日

    正常的,原理大概如下:

    views 是 namespace

    类似 categories/54edfc726361706be9110000-20150225164642/ 这是每个 category 的 cache_key 其中: categories 类似 table name 54edfc726361706be9110000-20150225164642 前半部分是 id,后半部分是 updated_at

    你这里 @categories 应该有 3 条记录,并且没有对 id 做处理 mongodb 生成的 id 都这么长的,ruby-china 不清楚哪处理了 )O( ...

    324cb0a5ab4174ae355d6a2a7c743788 根据当前 controller#action 生成

    你要纠结的话,给 @categories (Relation 实例) 写个 cache_key 方法,或许可以解决 ...

  • #35 楼 @chunlea 好吧,已修改。

  • 笑点低的人看到小明就笑了...

  • 数学里的减号,感觉意义不大。。 关键字 unless, 感觉意义不大。。

  • where 语句 为什么没起作用 at 2014年10月25日

    Houseinfo.where("rentway like ?", "%整租%") 百分号

  • 苹果电脑除了贵,其它优点都是骗人的。楼主不要上当~