首页 文章

在rails模型类中使用attr_accessor

提问于
浏览
1

请原谅我的noob问题 . 我是ruby和rails的新手,需要一些帮助来理解我在代码中遇到的attr_accessor

create_table "pets", force: :cascade do |t|
            t.string   "name"
            t.string   "colour"
            t.string   "owner_name"
            t.text     "identifying_characteristics"
            t.text     "special_instructions"
            t.datetime "created_at"
            t.datetime "updated_at"
            t.string   "email"
            t.string   "password"
          end

模型

class Pet < ActiveRecord::Base
  has_many :pet_photos
  cattr_accessor :form_steps do
    %w(identity characteristics instructions)
  end

  attr_accessor :form_step
  validates :email, presence: true
  validates :name, :owner_name, presence: true, if: -> { required_for_step?(:identity) }
  validates :identifying_characteristics, :colour, presence: true, if: -> { required_for_step?(:characteristics) }
  validates :special_instructions, presence: true, if: -> { required_for_step?(:instructions) }

  def required_for_step?(step)
    return true if form_step.nil?
    return true if self.form_steps.index(step.to_s) <= self.form_steps.index(form_step)
  end



end

class Pet::StepsController < ApplicationController
        include Wicked::Wizard
        steps *Pet.form_steps

        def show
          @pet = Pet.find(params[:pet_id])
          render_wizard
        end

        def update
          @pet = Pet.find(params[:pet_id])
          @pet.update(pet_params(step))

            if params[:images]

                params[:images].each do |image|
                @pet.pet_photos.create(image: image)
              end
            end

          render_wizard @pet
        end

        private

        def pet_params(step)
          permitted_attributes = case step
                                 when "identity"
                                   [:name, :owner_name]
                                 when "characteristics"
                                   [:colour, :identifying_characteristics]
                                 when "instructions"
                                   [:special_instructions]
                                 end

          params.require(:pet).permit(permitted_attributes).merge(form_step: step)
        end

      end

路线

PetThing::Application.routes.draw do
          resources :pets, only: [:new, :create, :index, :destroy] do
            resources :steps, only: [:show, :update], controller: 'pet/steps'
          end

          root to: 'pets#index'

1) 我只知道关于 attr_accessor 的内容,它只不过是一个对象的getter / setter . 我没有 form_step 作为我的宠物模型(宠物表)的属性 . 但是在模型中,有 attr_accessor :form_step . 如何getter / setter生成为 :form_step

2) :form_step 是Pet类的对象吗?

我并不完全理解Rails模型类中 attr_accessor 方法的用法 .

3) 请向我解释一下我必须为模型属性(宠物表属性或字段)生成getter / setter的场景

例如: attr_accessor :name attr_accessor :colour ..等

我们什么时候使用 attr_accessor 作为模型属性或字段?

2 回答

  • 4

    让我们从OOP开始,基本上 class 是定义其实例(即对象)的属性和行为的模板 .

    rails模型也是ruby类 . 其属性由 attr_accessor 定义,行为由 static and instance methods 定义 .

    考虑一个类 with attr_accessor

    class Animal
          //defines animal properties
          attr_accessor :legs
          //defines animal behavior
          def talk
          end
    end
    

    without attr_accessor

    class Animal
          //defines animal properties
          //getter
          def legs
            @legs
          end
          //setter
          def legs=(value)
            @legs = value
          end
    
          //defines animal behavior
          def talk
          end
    end
    

    两种表示完全相同 . attr_accessor 为我们自动添加getter和setter,让开发人员的生活更轻松 .

    让我们回答你的问题

    • Ruby attr_accessor 会自动为您添加这些,如前所述 .

    • form_step 其属性为 Pet class ,可以作为 petObj.form_step 进行访问 .

    • 如果表与Model关联/映射,那么您不必将表中的列定义为 attr_accessor ,Rails会自动为您服务 . 如果表中不存在字段或属性,则需要在 Model 中手动将其定义为 attr_accessor .

    我希望这回答了你的问题 .

  • 1

    部分Rails ' magic is that when you have a class Pet and a table pets, you get the accessors for all the columns in the table for free. It' s就像你已经为所有这些声明 attr-accessor 一样,只有你不需要 .

    在您的示例中,未在表中创建 #form_step . 但它是使用 attr_accessor 声明的 . 它就像普通的老红宝石一样工作 . 这会给你一个getter / setter(回答你的Q1) .

    它是Pet类的实例方法 . 你可以在Pet对象上调用它,比如 Pet.new.form_step = 5 (回答Q2) .

    但是你无法将你分配给 #form_step 的任何值保存到db . 因此,Q3的答案是,当您需要在对象之间传递一些消息(即调用方法)时,通常会这样做,但是您不需要将它们持久保存到db .

相关问题