从视图设置参数(最佳实践)

时间:2017-02-19 09:46:12

标签: ruby-on-rails

在视图(index.html.erb)中,我列出了所有文章:

<% @articles.each do |article| %>
...
 <%= link_to 'Show', article_path(article) %>
 <%= link_to 'Edit', edit_article_path(article) %>
 <%= link_to 'Delete', article_path(article), method: :delete, data: { confirm: 'Are you sure?' } %>
...
<% end %>

我想建立一个链接(只有管理员看到),管理员可以将文章属性“非法”设置为true / false。这些方面的东西:

<% if current_user.try(:admin?) %>
 <%= link_to "Mark as illegal", article, :method => "set_article_as_illegal" %>
<% end %> 

这显然不起作用。但我不知道如何以最好的方式做到这一点。我能想到的唯一方法就是笨拙(下面的选项B)。

方式,我认为应该这样做(或者至少是这些方面的事情)。

A)制作两个辅助函数:

def set_article_as_illegal(article)
  article.update_attribute :illegal, true
end

def set_article_as_legal(article)
  article.update_attribute :illegal, false
end

并以某种方式称他们为:

<%= link_to "Mark as illegal", article, :method => "set_article_as_illegal" %>

...但我不知道如何创建一个执行方法并接受输入的链接(或按钮)(在这种情况下应该是文章)。

B)制作一个新的控制器(或其中一组)。

这似乎是错误的,但这是唯一的方法,我能够在这一点上实现我想要达到的目标,这就是为什么我提到它。所以这意味着:

  • 制作路线:get '/make_article_illegal', to: 'article#make_illegal'
  • 制作另一条路线:get '/make_article_legal', to: 'article#make_legal'
  • 制作一个处理器make_illegal来处理非法操作。
  • 制作另一个处理器make_legal,使其合法化。

但这看起来太笨拙了。

必须有一个明显的方法来做到这一点,我错过了。

1 个答案:

答案 0 :(得分:2)

当然,有无穷无尽的(几乎)方式。一种方法是。

# routes.rb
get '/update_article_legality/:id/:illegal' => 'article#update_legality', as: :update_article_legality

# in the view
= link_to 'Make legal',   update_article_legality_path(id: article.id, illegal: 'false')
= link_to 'Make illegal', update_article_legality_path(id: article.id, illegal: 'true')

# in controller
def update_legality
  article = Article.find(params[:id])
  illegal = params[:illegal] == 'false' ? false : true

  article.update_attribute :illegal, illegal
end

MVC的另一种方式和更多方法是实际创建两个控制器,每个控制器只有一个方法来更新合法性。也许这对你的情况来说太过分了,但至少这是理论。

# app/controllers/article/illegal_controller.rb
class Article::IllegalController < ApplicationController
  def update
    article = Article.find(params[:id])
    article.update_attribute :illegal, false
  end
end

# app/controllers/article/legal_controller.rb
class Article::LegalController < ApplicationController
  def update
    article = Article.find(params[:id])
    article.update_attribute :illegal, true
  end
end

# routes.rb
get '/make_article_legal' => 'article/legal#update', as: :make_article_legal
get '/make_article_illegal' => 'article/illegal#update', as: :make_article_illegal

# in the view
= link_to 'Make legal',   make_article_legal_path(id: article.id)
= link_to 'Make illegal', make_article_illegal_path(id: article.id)

PS:我没有测试过这段代码,所以可能会出现奇怪的拼写错误,但至少它在理论上是有效的。

有一篇关于此事的有趣文章here