Ruby on rails 在Rails视图中访问特定于模型的常量

Ruby on rails 在Rails视图中访问特定于模型的常量,ruby-on-rails,ruby,constants,Ruby On Rails,Ruby,Constants,我在运行Rails 4 我有一个名为Challenge的模型,我在数据库中以0-4的形式存储每个挑战的状态 但是0-4不是很有语义,所以我想定义几个变量(我假设一个常量),这样在任何控制器或视图中,我都可以通过调用常量来访问数字: # Challenge.rb class Challenge < ActiveRecord::Base SUGGESTED = 0 APPROVED = 1 OPEN = 2 VOTING = 3 CLOSED = 4 end 设置状态变量

我在运行Rails 4

我有一个名为
Challenge
的模型,我在数据库中以0-4的形式存储每个挑战的
状态

但是0-4不是很有语义,所以我想定义几个变量(我假设一个常量),这样在任何控制器或视图中,我都可以通过调用常量来访问数字:

# Challenge.rb
class Challenge < ActiveRecord::Base
  SUGGESTED = 0
  APPROVED = 1
  OPEN = 2
  VOTING = 3
  CLOSED = 4
end

设置状态变量的最佳方法是什么,以便可以在我需要它们的任何地方访问它们?(即,
@challenge
变量存在的任何地方)

您应按以下方式访问它们:

Challenge::CLOSED
class Challenge < ActiveRecord::Base
  SUGGESTED = 0
  APPROVED = 1
  OPEN = 2
  VOTING = 3
  CLOSED = 4

  #defines:
  # - suggested?
  # - approved?
  # - ...
  %w(suggested approved open voting closed).each do |state|
    define_method "#{state}?" do
      status == self.class.const_get(state.upcase)
    end
  end

  #if you prefer clarity, define each method:

  def suggested?
    status == SUGGESTED
  end

  #etc...
end
由于您的
CLOSED
常量是在类中定义的,因此需要使用scope resolution操作符访问该常量。因此,如果您的视图是这样检查的:

# challenge/_details.html.erb
<% if @challenge.status == Challenge::CLOSED %>
  Challenge is closed, broheim!
<% end %>
#挑战/_details.html.erb
挑战结束了,布罗海姆!

编写此类语句是一个非常糟糕的主意:对象必须处理自己的逻辑。 想象一下,如果有一天您决定合并状态,您会更改代码库中的每个条件吗?不,您应该使用一种处理逻辑的方法

我会做以下几件事:

Challenge::CLOSED
class Challenge < ActiveRecord::Base
  SUGGESTED = 0
  APPROVED = 1
  OPEN = 2
  VOTING = 3
  CLOSED = 4

  #defines:
  # - suggested?
  # - approved?
  # - ...
  %w(suggested approved open voting closed).each do |state|
    define_method "#{state}?" do
      status == self.class.const_get(state.upcase)
    end
  end

  #if you prefer clarity, define each method:

  def suggested?
    status == SUGGESTED
  end

  #etc...
end
类挑战
那么在你看来,

<% if @challenge.closed? %>


考虑到我的if语句已经引用了@challenge变量,这有点多余。有没有一种方法可以做到语义如此之语义以至于读起来像英语?嘿,thanx,这对我来说非常有用。我建议你在这种情况下使用散列作为常量。为什么?因为它将减少模型中不同常数的数量。类似于:
STATUSES={建议的:0,批准的:1,打开的:2,等等:…}
并像
Challenge::STATUSES那样访问它。批准的
似乎没有很好的语义。在开源项目的模型中包含的代码数量也相当混乱。也许你可以详细解释一下为什么@MrYoshiji的想法如此糟糕?如果方法有意义,那么创建方法也没什么大不了的,比将内部逻辑置于模型之外要好得多@顺便说一句,Yoshiji先生的想法很好。顺便说一句,它怎么可能比
@challenge.closed?
?更具语义呢?就语义而言,我指的是代码实现。我想让人们看看挑战模型,了解其中的每一部分,你的想法与@MrYoshiji的相比有太多的认知开销,但我很欣赏你的回应!我坚持,但将模型的逻辑扩展到类之外是一个非常糟糕的主意,这与OOP的基本原理相反。。