Rails 4: неопределенный метод "класс делегата отношения" для модели: класс
я пытаюсь следовать этому учебнику coderwall о создание системы приглашений с областью видимости для Rails.
в моем приложении Rails 4 у меня есть следующие модели:
class User < ActiveRecord::Base
has_many :administrations
has_many :calendars, through: :administrations
has_many :invitations, :class_name => "Invite", :foreign_key => 'recipient_id'
has_many :sent_invites, :class_name => "Invite", :foreign_key => 'sender_id'
end
class Calendar < ActiveRecord::Base
has_many :administrations
has_many :users, through: :administrations
has_many :invites
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Invite < ActiveRecord::Base
belongs_to :calendar
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
end
вот соответствие между моими моделями и моделями из учебника:
-
User
User
-
Calendar
UserGroup
-
Administration
Membership
-
Invite
Invite
я сейчас в создание нового приглашения:
- на
Invite
модель была обновлена с иgenerate_token
метод. - на с
create
действие.
однако, когда я посещаю представление редактирования календаря, чтобы заполнить форму приглашения, я получаю следующую ошибку:
NoMethodError in CalendarsController#edit
undefined method `relation_delegate_class' for Invite:Class
def edit
@user = current_user
@invite = @calendar.invites.build
authorize @calendar
end
проблема, похоже, исходит от @invite = @calendar.invites.build
линии.
-----
обновление: вот содержание моей модели приглашения:
class Invite < ActiveRecord::Base
belongs_to :calendar
belongs_to :sender, :class_name => 'User'
belongs_to :recipient, :class_name => 'User'
before_create :generate_token
def generate_token
self.token = Digest::SHA1.hexdigest([self.calendar_id, self.recipient_role, Time.now, rand].join)
end
end
-----
обновление 2: in этот вопрос, автор объясняет, что проблема может исходить от CanCanCan & Rolify. Я не использую эти камни, но я использую ученый. Думал, что это будет полезно в контексте моего вопроса.
-----
обновление 3: здесь тоже миграция, которую я использовал для Invite
модель:
class CreateInvites < ActiveRecord::Migration
def change
create_table :invites do |t|
t.string :email
t.integer :calendar_id
t.integer :sender_id
t.integer :recipient_id
t.string :recipient_role
t.string :token
t.timestamps null: false
end
end
end
мне интересно, может ли проблема быть вызвана t.string :recipient_role
С role
данного user
существуют только в administration
таблица, для данного calendar
: если :recipient_role
автоматически интерпретируется как recipient.role
по рельсам, то, может быть, это вызывает ошибку?
-----
обновление 4: вот содержание CalendarsController:
class CalendarsController < ApplicationController
before_action :set_calendar, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
# GET /calendars
# GET /calendars.json
def index
@user = current_user
@calendars = @user.calendars.all
end
# GET /calendars/1
# GET /calendars/1.json
def show
@user = current_user
@calendar = @user.calendars.find(params[:id])
authorize @calendar
end
# GET /calendars/new
def new
@user = current_user
@calendar = @user.calendars.new
authorize @calendar
end
# GET /calendars/1/edit
def edit
@user = current_user
@invite = @calendar.invites.build
authorize @calendar
end
# POST /calendars
# POST /calendars.json
def create
@user = current_user
@calendar = @user.calendars.create(calendar_params)
authorize @calendar
respond_to do |format|
if @calendar.save
current_user.set_default_role(@calendar.id, 'Owner')
format.html { redirect_to calendar_path(@calendar), notice: 'Calendar was successfully created.' }
format.json { render :show, status: :created, location: @calendar }
else
format.html { render :new }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /calendars/1
# PATCH/PUT /calendars/1.json
def update
@user = current_user
@calendar = Calendar.find(params[:id])
authorize @calendar
respond_to do |format|
if @calendar.update(calendar_params)
format.html { redirect_to calendar_path(@calendar), notice: 'Calendar was successfully updated.' }
format.json { render :show, status: :ok, location: @calendar }
else
format.html { render :edit }
format.json { render json: @calendar.errors, status: :unprocessable_entity }
end
end
end
# DELETE /calendars/1
# DELETE /calendars/1.json
def destroy
@user = current_user
@calendar.destroy
authorize @calendar
respond_to do |format|
format.html { redirect_to calendars_url, notice: 'Calendar was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_calendar
@calendar = Calendar.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def calendar_params
params.require(:calendar).permit(:name)
end
end
-----
обновление 5: вот такие логи:
Started GET "/calendars/2/edit" for ::1 at 2015-09-14 11:44:13 -0700
Processing by CalendarsController#edit as HTML
Parameters: {"id"=>"2"}
Calendar Load (0.1ms) SELECT "calendars".* FROM "calendars" WHERE "calendars"."id" = ? LIMIT 1 [["id", 2]]
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.3ms)
NoMethodError (undefined method `relation_delegate_class' for Invite:Class):
app/controllers/calendars_controller.rb:30:in `edit'
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/_source.erb (6.0ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.8ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.7ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1@global/gems/actionpack-4.2.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (68.9ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (0.5ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (39.3ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (0.4ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.4ms)
Rendered /Users/TXC/.rvm/gems/ruby-2.2.1/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (94.2ms)
-----
обновление 6: я только что понял, что у меня нет
def invite_params
params.require(:invite)
end
на
1 ответов
проблема была сложно определить, особенно только из содержания вопроса.
ПРОБЛЕМА
причина, по которой я получал undefined method 'relation_delegate_class' for Invite:Class
ошибка в том, что Invite
больше не считалось моделью по рельсам.
ОСНОВНАЯ ПРИЧИНА ПРОБЛЕМЫ
когда я создал Invite
Мейлер, я побежала rails g mailer Invite
вместо rails g mailer InviteMailer
.
из-за этого, Invite
как переопределение почтовой программы Invite
как модель, следовательно, создавая ошибки, как только методы были применены к экземплярам Invite
модель.
КАК МЫ ЭТО ВЫЯСНИЛИ
один из моих друзей, который намного опытнее в программировании, чем я, определил проблему, настроив @invite = @calendar.invites.build
строка, которая вызывала ошибку.
это привело нас в конце концов Invite.first
в консоли rails: в то время как мы должны были получить либо экземпляр Invite
class, или nil, мы фактически получили ошибку.
С .first
должен быть допустимым методом на любой модели ActiveRecord, мы поняли, что Invite
не считалось моделью по рельсам.
КАК МЫ ЭТО ИСПРАВИЛИ
как только мы определили проблему, исправление было довольно простым:
- мы изменили название
Invite
Мейлер отinvite.rb
toinvite_mailer.rb
- во вновь переименованном
invite_mailer.rb
файл, мы заменилиclass Invite < ApplicationMailer
Сclass InviteMailer < ApplicationMailer
я надеюсь, что это может быть полезно для других пользователей переполнения стека, которые могут получить аналогичный relation_delegate_class
ошибка.