Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 我怎样才能设置;“全球”;可在Rails的控制器和模型中访问的变量_Ruby_Variables_Ruby On Rails 4_Global Variables_Activesupport Concern - Fatal编程技术网

Ruby 我怎样才能设置;“全球”;可在Rails的控制器和模型中访问的变量

Ruby 我怎样才能设置;“全球”;可在Rails的控制器和模型中访问的变量,ruby,variables,ruby-on-rails-4,global-variables,activesupport-concern,Ruby,Variables,Ruby On Rails 4,Global Variables,Activesupport Concern,我有一个表,其中有一组条目。我希望在我的模型和控制器中以变量的形式访问这些条目,而无需每次查询数据库来设置这些变量 通过为我的模型和控制器创建重复的“关注点”,我可以让它工作。我还可以在ApplicationController中设置全局变量。或者我可以在我需要它们的每个地方初始化它们。rails设置和访问可以在控制器和模型中访问的全局变量的正确方法是什么 类ItemType 你有很多东西吗 结束 类项目 属于:项目类型 属于:富 结束 福班 你有很多东西吗 def build_项目 bar\u

我有一个表,其中有一组条目。我希望在我的模型和控制器中以变量的形式访问这些条目,而无需每次查询数据库来设置这些变量

通过为我的模型和控制器创建重复的“关注点”,我可以让它工作。我还可以在ApplicationController中设置全局变量。或者我可以在我需要它们的每个地方初始化它们。rails设置和访问可以在控制器和模型中访问的全局变量的正确方法是什么

类ItemType
你有很多东西吗
结束
类项目
属于:项目类型
属于:富
结束
福班
你有很多东西吗
def build_项目
bar\u item\u type=ItemType.find\u by(:name=>“bar”)
self.items.build(
:foo_id=>self.id,
:item\u type\u id=>bar\u item\u type.id
)
结束
结束
类项控制器
def更新
bar\u item\u type=ItemType.find\u by(:name=>“bar”)
@更新(:item\u type\u id=>bar\u item\u type.id)
结束
结束

在这个示例中,您可以看到我在我的Foo模型和ItemsController中声明了
bar\u item\u type
变量。我希望通过能够为rails项目创建和访问该变量一次,而不必到处进行相同的数据库调用,从而干涸我的代码库。

我反对这种硬编码或依赖于DB状态的代码。如果你必须这样做,以下是我知道的一种方法:

# models
class ItemType < ActiveRecord::Base
  has_many :items

  # caches the value after first call
  def self.with_bar
    @@with_bar ||= transaction { find_or_create_by(name: "bar") }
  end

  def self.with_bar_id
    with_bar.id
  end
end

class Item < ActiveRecord::Base
  belongs_to :item_type
  belongs_to :foo

  scope :with_bar_types, -> { where(item_type_id: ItemType.with_bar_id) }
end

class Foo < ActiveRecord::Base
  has_many :items  

  # automatically sets the foo_id, no need to mention explicitly
  # the chained with_bar_types automatically sets the item_type_id to ItemType.with_bar_id
  def build_item
    self.items.with_bar_types.new
  end
end

# Controller
class ItemsController
  def update
    @item.update(item_type_id: ItemType.with_bar_id)
  end
end
#模型
类ItemType{where(item_type_id:ItemType.with_bar_id)}
结束
类Foo
如果必须使用常数,有几种方法。但您必须考虑到,您正在实例化一个ActiveRecord模型对象,该对象依赖于数据库中存在的数据。不建议这样做,因为现在模型和控制器逻辑依赖于数据库中的数据。如果您已经为数据库设定了种子,并且它不会改变,那么这可能还可以

class ItemType
  BAR_TYPE ||= where(:name => "bar").limit(1).first 

  has_many :items
end
现在,无论何时需要此对象,都可以这样称呼它:

bar_item_type  = ItemType::BAR_TYPE

我不确定你的例子是否清楚你为什么要这样做。您真的会在应用程序中使用
ItemType.find_by(:name=>“bar”)
?在用例中使用全局变量打破了MVC和基本Rails惯例。你首先需要问自己为什么你认为你需要这样做。可能有更好更传统的方法来做。我想这是我的问题。使用上述示例,传统/更好的方法是什么?我想要一个在这两种用例中都可以访问的变量。问题是,如何确保
ItemType.find\u by(:name=>“bar”)
甚至会返回任何内容?您的代码对数据库进行了假设。数据库的种子是特定的项目类型。数据库被假定并设计为拥有它们。OP可能还希望验证项目名称的唯一性type@lacostenycoder:那么OP应该在文章的示例代码中提到这一点。无论如何,这很容易解决。我同意,而且我认为你提供了一个很好的答案。谢谢。我相信这就是我要找的。我不知道您可以像这样在ItemType模型上声明
BAR\u TYPE
。这是有效的ruby语法,但不完全是传统的Rails样式。下面的Surya的答案是更传统的Rails方式,并且有一些额外的好处,正如我的例子所示,这更像是一种黑客行为。