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 to invite_mailer.rb
  • во вновь переименованном invite_mailer.rb файл, мы заменили class Invite < ApplicationMailer С class InviteMailer < ApplicationMailer

я надеюсь, что это может быть полезно для других пользователей переполнения стека, которые могут получить аналогичный relation_delegate_class ошибка.