Этот вопрос следует за Rails has_many :through association: save instance into join table, и я повторяю здесь все для большей ясности.Rails has_many: через ассоциацию: Обновление всех 3 моделей одновременно
В нашем приложении Rails, есть 3 модели:
class User < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :calendars, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Calendar < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :users, through: :administrations
end
А вот соответствующие Миграции:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :email
t.integer :total_calendar_count
t.integer :owned_calendar_count
t.timestamps null: false
end
end
end
class CreateAdministrations < ActiveRecord::Migration
def change
create_table :administrations do |t|
t.references :user, index: true, foreign_key: true
t.references :calendar, index: true, foreign_key: true
t.string :role
t.timestamps null: false
end
end
end
class CreateCalendars < ActiveRecord::Migration
def change
create_table :calendars do |t|
t.string :name
t.timestamps null: false
end
end
end
Вот что мы пытаемся достичь:
Когда зарегистрированный пользователь (current_user
) создает календарь, мы должны:
- Создать новую
@calendar
и сохранить его в таблицу - Календаря Присвоить «Creator» роль для пользователя (current_user) для этого вновь созданного календаря через колонку Роли в таблице администрирования
- увеличивают
total_calendar_count
и столбцыowner_calendar_count
таблицы пользователей
Для этого мы считаем, что нам нужно работать над календарями # create.
В CalendarsController, у нас уже есть следующий код:
def create
@calendar = current_user.calendars.create(calendar_params)
if @calendar.save
flash[:success] = "Calendar created!"
redirect_to root_url
else
render 'static_pages/home'
end
end
И мы собираем данные от пользователей через следующие _calendar_form.html.erb
формы:
<%= form_for(@calendar) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_field :name, placeholder: "Your new calendar name" %>
</div>
<%= f.submit "Create", class: "btn btn-primary" %>
<% end %>
Мы рассматриваем обновление контроллера следующим образом:
def create
@calendar = current_user.calendars.create(calendar_params)
@current_user.total_calendar_count += 1
@current_user.owned_calendar_count += 1
current_user.administrations << @calendar.id
@calendar.administration.role = 'Creator'
if @calendar.save
flash[:success] = "Calendar created!"
redirect_to root_url
else
render 'static_pages/home'
end
end
ActiveRecord::AssociationTypeMismatch in CalendarsController#create
Administration(#70307724710480) expected, got Fixnum(#70307679752800)
unless record.is_a?(reflection.klass) || record.is_a?(reflection.class_name.constantize)
message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
raise ActiveRecord::AssociationTypeMismatch, message
end
end
app/controllers/calendars_controller.rb:7:in `create'
Как мы можем сделать это к?
'@calendar = current_user.calendars.create (calendar_params)' должен быть '@calendar = Calendar.create (calendar_params)' для создания нового календаря. Вы получаете ошибку b/c 'current_user.calendars' не возвращает то, что имеет метод создания класса Calendar. –
@steveklein 'current_user.calendars.create (calendar_params)' отлично работает, даже если 'current_user.calendars' не возвращает календаря. –
Узнал что-то новое ... спасибо @Arslan. –