【问题标题】:Simple association architecture and implementation in ruby on railsruby on rails 中的简单关联架构和实现
【发布时间】:2013-03-27 16:44:03
【问题描述】:

关于我面临的一个简单问题的快速问题(我想以此作为一种方式来更深入地了解有关关联和 Rails 的一些事情)。如下:

两个关联的模型是

class Employee < ActiveRecord::Base
  attr_accessible :name
  attr_accessible :age

  belongs_to :role
  attr_accessible :role_id
end

class Role < ActiveRecord::Base
  attr_accessible :title
  attr_accessible :salary

  has_many :employees
end

这样每个新员工都有固定的工资,根据他的角色(大多数时候都是这种情况)。但是,如果我想为特定员工设置不同的工资怎么办?

到目前为止,我使用simple_form 编写了以下内容:

<%= f.input :name, label: 'Employee Name', :required => true %>
<%= f.association :role, as: :radio_buttons, :required => true %>
<%= f.input :salary, label: 'Employee Salary', :input_html => { :value => 0 }, :required => true %>

这当然会给我一个can't mass assign protected attributes: salary 错误。

为了解决这个问题,我将attr_accessible :salary 添加到Employee 模型中,但这只是将错误更改为unknown attribute: salary

据我了解,我必须首先在新员工中更改某些内容,然后在员工模型和控制器中进行更改,以便它接受薪水值并知道如何处理它,对吗?

我也看到使用了accepts_nested_attributes_for,但我不完全确定它应该放在关联的哪一边——因为我也不完全确定关联的架构是最好的。

【问题讨论】:

    标签: ruby-on-rails ruby associations nested-attributes simple-form


    【解决方案1】:

    如果您实际上希望允许在Employee 上指定自定义工资,则需要将salary 列添加到employees 表中。在您的终端中,创建一个新的迁移并应用它

    rails generate migration AddSalaryToEmployees salary:integer
    RAILS_ENV=development rake db:migrate
    

    顺便说一句,你不需要多次调用attr_accessible;它接受任意数量的符号

    attr_accessible :name, :age, :role_id, :salary
    

    另外,既然你提到了它,我会评论它:accepts_nested_attributes_for 目前在你的模型中没有位置(鉴于你到目前为止显示的代码)。


    回答您在评论中提出的问题:

    这不是代码重复(我的意思是两种模型都有薪水)吗?

    不,它们有两个不同的目的。 Role 中的:salary 是应用于与Role 关联的所有Employees 的默认薪水。 Employee 上的 :salary 是针对特殊情况的“替代”,即 Employee 的薪水不符合他们所关联的 Role 的模式。

    • 仅仅为此目的创建自定义Role 是没有意义的(假设自定义薪水是Employee 的唯一区别)
    • 您不能更改Role 本身的薪水,因为这会影响与该Role 关联的另一个Employees 的薪水

    那不需要另一种方法(如果没有专门设置,确保角色薪水被设置为员工的薪水)?

    另一种方法?否。如果尚未设置“覆盖”,则在 Employee 上为 salary 自定义现有 attr_reader 以从 Role 返回默认值?如果你愿意

    def salary
      return role.salary if read_attribute(:salary).blank?
      read_attribute(:salary)
    end
    

    【讨论】:

    • 这不是代码重复吗(我的意思是在两个模型中都有salary)?并且不需要另一种方法(如果没有专门设置,则确保将角色薪水设置为员工的薪水)? (我多次调用attr_accessible,因为我不喜欢将所有属性都放在一行中,我想我应该将其称为一个并将所有属性缩进不同的行)
    • 非常感谢,我的印象是我应该避免你所描述的一切。也感谢您对salary 方法的澄清。 :)
    • 我刚做了,但我想知道read_attribute(:salary).blank? ? role.salary : read_attribute(:salary)是否是编写salary方法的“rubier”方式?
    • 这很主观,但我会说。此外,像您建议的三元运算符对我来说可读性较差。作为单行符,我什至更喜欢 read_attribute(:salary) || role.salary 而不是三元运算符。
    猜你喜欢
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    相关资源
    最近更新 更多