0

Быстрый вопрос о простой проблеме, с которой я столкнулся (и я хочу использовать как способ понять несколько вещей об ассоциациях и рельсах на более глубоком уровне). Здесь идет:Простая ассоциативная архитектура и реализация в рубине на рельсах

Две связанные модели

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, но я не совсем уверен, в какой части ассоциации он должен идти - поскольку я не совсем уверен, что ассоциация также построена наилучшим образом.

ответ

1

Вы должны добавить salary столбец в таблице employees, если вы на самом деле хочет, чтобы обычай зарплаты должны быть указаны наEmployee. В терминале, создать новую миграцию и применять его

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 в настоящее время не имеет места в вашей модели (с учетом кода вы показали до сих пор).


Чтобы ответить на вопросы, поднятые в вашем комментарии:

Не дублирование коды (с зарплатой в обеих моделях я имею в виду)?

Нет, они служат в двух разных целях. :salary в Role - это заработная плата по умолчанию, применяемая ко всем Employees, связанным с этим Role. :salary на Employee является «переопределением» для особых обстоятельств, когда зарплата Employee не соответствует форме Role, с которой они связаны.

  • Это не имело бы смысла создавать пользовательские Role только для этой цели (предполагается, что пользовательское зарплату единственное различие в Employee)
  • Вы не можете изменить зарплату на самом Role, потому что что повлияло бы на зарплату другого Employees, связанного с этим Role

И не что нужен другой метод (чтобы убедиться, что роль заработной платы устанавливается в качестве заработной платы работника, если ни я специально настроены)?

Другой способ? Нет. Настроить существующий attr_reader для salary на Employee, чтобы вернуть значение по умолчанию из Role, если «переопределение» не было установлено? Если вы хотите

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

Разве это не дублирование кода (с «зарплатой» в обеих моделях я имею в виду)? И не нужен ли другой метод (чтобы заработная плата была установлена ​​как зарплата сотрудника, если она не установлена)? (Я много раз вызываю 'attr_accessible', потому что мне не нравится иметь все атрибуты в одной строке, я думаю, я должен просто назвать его одним и отступом все атрибуты в разных строках, хотя) – sebkkom

+0

Я обновил свой ответ, отвечая на ваши вопросы. – deefour

+0

Большое спасибо, у меня создалось впечатление, что я должен избегать того, что вы описываете, просто отлично. Спасибо за разъяснение о методе «зарплата». :) – sebkkom