如何在控制器层使用RubyonRails模型方法

如何在控制器层使用RubyonRails模型方法,ruby,ruby-on-rails-6,Ruby,Ruby On Rails 6,我对RubyonRails非常陌生,虽然我学习得相当快,但在模型层和控制器层之间进行交互时遇到了一些语法问题。我正在做一个模拟侏罗纪公园管理应用程序的玩具项目。db模式如下所示: schema.rb ActiveRecord::Schema.define(version: 2021_01_24_134125) do create_table "cages", force: :cascade do |t| t.string "name"

我对RubyonRails非常陌生,虽然我学习得相当快,但在模型层和控制器层之间进行交互时遇到了一些语法问题。我正在做一个模拟侏罗纪公园管理应用程序的玩具项目。db模式如下所示:

schema.rb

ActiveRecord::Schema.define(version: 2021_01_24_134125) do

  create_table "cages", force: :cascade do |t|
    t.string "name"
    t.integer "max_capacity"
    t.integer "number_of_dinosaurs"
    t.string "power_status"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "dinosaurs", force: :cascade do |t|
    t.string "name"
    t.string "species"
    t.string "diet_type"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.integer "cage_id", null: false
    t.index ["cage_id"], name: "index_dinosaurs_on_cage_id"
  end

  add_foreign_key "dinosaurs", "cages"
end
我已经在恐龙和cage模型中编写了一些助手方法,但是当我尝试在cage.controller或恐龙.controller中实际使用它们时,我遇到了一些如何使用它们的问题。这些方法如下:

cage.rb

class Cage < ApplicationRecord
    has_many :dinosaurs
    validates :name, :max_capacity, :power_status, presence: true
    validates_uniqueness_of :name

    def dinosaur_count
        dinosaurs.count
    end

    def at_capacity?
        return dinosaur_count == max_capacity
    end

    def is_powered_down?
        return power_status == "DOWN"
    end

    def has_herbivore
        dinosaurs.where(diet_type:"Herbivore").count > 0
    end

    def has_carnivore
        dinosaurs.where(diet_type:"Carnivore").count > 0
    end

    def belongs_in_cage(diet)
        return true if dinosaur_count == 0
        return false if diet != 'Carnivore' && has_carnivore
        return false if diet != 'Herbivore' && has_herbivore
        return true if dinosaurs.where(diet_type: diet).count > 0
        return false
    end

    def has_dinosaurs?
        return dinosaur_count > 0
    end

end

有人能帮我做这件事吗?

啊,是的,
@cage.断电了吗?
返回一个布尔值,所以你可以:

if @cage.is_powered_down?

有趣的项目!您可能希望发布这些类定义以获得反馈。在“设置”对象之后,您是否在任何时候保存它们?@jad您是指在cage变量上调用的.save()方法吗?@davidridge和@jad指出了两个明显的问题。实际上不可能完全回答这个问题,因为您从控制器中截取的代码太多了。这里有一种很大的气味,就是你的控制器在问
@cage
问题,而不是告诉它更新和响应。这意味着您的业务逻辑正在从模型(它所属的位置)泄漏到控制器中。是的。控制器中的逻辑越少越好,因为它们很难测试。是的,我试着检查@cage.is\u powered\u down?==是的,但是它好像被忽略了,没有产生任何错误。这是一个有用的Ruby课程,我想:总是考虑对象的类。代码>“true”是一个字符串,您将其与布尔值进行比较。您可以在
irb
中尝试,并发现:
(1==1)=“true”
为false。如果您测试了
@cage.is\u powered\u down?.class
,您会发现它是
TrueClass
false class
。不管怎样,你可以直接测试布尔值是真是假,而不需要将它与你知道的是真是假的东西进行比较。啊,是的,那实际上是一个打字错误,我的意思是只键入真而不是“真”。我可以简单地不包括这个等式吗?可以,这将是有效的语法,但在ruby中这样做是不寻常的。您希望布尔值可以直接测试。谢谢@David Aldridge!我很感激。我想我可能已经修好了。实际上,我能够直接在模型本身中进行这些数据验证,并且在任何验证失败时停止表单提交。这听起来像是更好的练习吗?
if @cage.is_powered_down? == "true"
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @cage.errors, status: :unprocessable_entity }
      else
        format.html { redirect_to @cage, notice: "Cage was successfully updated." }
        format.json { render :show, status: :ok, location: @cage }
      end
if @cage.is_powered_down?