ruby-on-rails – 从多个地方渲染javascript:Rails方式

我有一个通过 javascript呈现的模态表单.该模型称为书.
# controllers/books_controller.rb

def new
  @book = Book.new
end

def create
  @book = Book.find(params[:id])
  @book.save
end

我没有使用新的和编辑html,而是使用coffeescript:

# views/new.js.coffee

CustomModal.open "<%= j render('books/modal_form',book: @book) %>"

# views/create.js.coffee

<% if @book.valid? %>
CustomModal.hide()
# Other callback scripts for showing alert,etc
<% else %>
# Script for showing errors in the modal
<% end %>

以及触发模态的链接

= link_to "Create Book",new_book_path,remote: true

现在,我面临的问题是这个链接只是在书的列表页面上使用.因此,在创建图书时,js回调会触发警报并使用更改更新列表.

现在我必须在另一个页面添加此按钮,其中没有列表,所以我需要一个不同的回调(无论哪个回调都没关系).

所以,我必须添加到create.js.coffee之类的东西:

# views/create.js.coffee

<% if @book.valid? %>
CustomModal.hide()
# if the list exists
#   show alert
#   update lists
# else
#   do different things
# end
<% else %>
# Script for showing errors in the modal
<% end %>

这看起来很脏,但并不是那么糟糕.问题是我现在有超过3个条件,因为沿着webapp多次使用“Create Book”按钮.

那么,关于设计模式的任何想法呢?

解决方法

你正在做的事情并不可怕,但你可以做一些事情来清理它.我建议将业务逻辑从视图和控制器中移出,并使用Presenter模式和Helper模式.如今,这些模式已经很好地记录下来并且具有许多好处,包括

>促进瘦身控制者
>推广更小,更简洁的代码
>推动得墨忒耳法则
>使单元测试更容易

这是Presenter模式的一个非常好的描述:
https://gist.github.com/somebox/5a7ebf56e3236372eec4
要么:
http://eewang.github.io/blog/2013/09/26/presenting-the-rails-presenter-pattern/

基本上,它的工作方式是将业务逻辑移动到一个称为“演示者”的单独类中.此类包含您通常保留在控制器中的逻辑.

助手也有很好的记录,工作方式大致相同,但对于观点而言.助手比视图中的逻辑更容易测试.欲获得更多信息:
http://api.rubyonrails.org/classes/ActionController/Helpers.html

它可能看起来像这样(请注意,这只是未经测试的’伪’代码,我用它来说明模式):

# app/controllers/books_controller.rb
    helper BooksHelper

    def create
        book = Book.find(params[:id])
        book.save
        @presenter = BookPresenter(book)
    end

    # app/presenters/book_presenter.rb
# move your 'fat' controller logic here

    class BookPresenter
        attr_reader :book,:page_type

        def initialize(book,options={})
            @book = book
        end

        private

        def page_type
            # custom code here for determining page type
        end

        ...
    end

# app/helpers/books_helper.rb
# move your view logic here
module BooksHelper
        def custom_modal(book_presenter)
            if book_presenter.book.is_valid
              handle_valid_book(book_presenter)
            else
               # handle invalid book
            end
        end

        def handle_valid_book(book_presenter)
          custom_list_modal if book_presenter.page_type == 'has_list'
          custom_listless_modal if book_presenter.page_type == 'listless'
          # other conditions
        end

        def custom_list_modal
          # modularized JavaScript for pages with a list
        end

        def custom_listless_modal
        # modularized JavaScript for pages without a list
        end

        ...
    end

因此,在这种情况下,可以使用RSpec或您正在使用的任何测试框架在您的应用程序中轻松地对业务逻辑进行单元测试. JavaScript复杂性降低,测试变得更简单.如果您愿意,可以在不同的部分中单独定义JS输出,或者只是从辅助模块返回实际的JS.这是一个复杂的模式,最初采用,但随着时间的推移,一切都可能会感觉更自然,模块化,易于维护.

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...