簡體   English   中英

Rails 4:Model:Class 的未定義方法“relation_delegate_class”

[英]Rails 4: undefined method `relation_delegate_class' for Model:Class

我正在嘗試遵循有關為 Rails 創建范圍邀請系統的coderwall 教程。

在我的 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模型已更新為before_create過濾器和generate_token方法。
  • Invites控制器已更新為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 :在這個問題中,作者解釋了問題可能來自CanCanCan & Rolify。 我不使用這些寶石,但我使用 Pundit。 認為這在我的問題的背景下會很有用。

————

更新 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

Invites控制器中:這可能是問題的根源嗎?

————

知道此錯誤消息的含義以及如何解決此問題嗎?

這個問題很難識別,尤其是從問題的內容來看。

問題

我得到undefined method 'relation_delegate_class' for Invite:Class錯誤的undefined method 'relation_delegate_class' for Invite:Class的原因是因為Invite不再被 Rails 視為模型。

問題的根源

當我創建Invite郵件程序時,我運行了rails g mailer Invite而不是rails g mailer InviteMailer

正因為如此, Invite作為郵件覆蓋Invite的方法被應用到的情況下,只要一個模型,從而產生錯誤Invite模型。

我們是怎么想出來的

我的一位朋友在編程方面比我更有經驗,通過調整導致錯誤的@invite = @calendar.invites.build行確定了問題。

這導致我們最終在 rails 控制台中運行Invite.first :雖然我們應該得到Invite類的實例或 nil,但我們實際上得到了一個錯誤。

由於.first應該是任何 ActiveRecord 模型上的有效方法,我們意識到Invite不被 Rails 視為模型。

我們如何修復它

一旦我們確定了問題,修復它就非常簡單:

  • 我們將Invite郵件程序的名稱從invite.rbinvite_mailer.rb
  • 在新重命名的invite_mailer.rb文件中,我們將class Invite < ApplicationMailer替換為class InviteMailer < ApplicationMailer

我希望這對可能遇到類似relation_delegate_class錯誤的其他Stack Overflow 用戶有用。

如果您忘記從 ActiveRecord 繼承模型,也會發生這種情況。 因此它變成了一個簡單的 ruby​​ 類。

class MyPlainModel
end

另一個原因是您的 sti 列指向無效的列類。 我以某種方式結束了:

=> #<Mailerlite::Subscriber:0x00005559d469bd00
...
 user_id: 2777,
 user_type: "NilClass",
...
>

導致NoMethodError: undefined method 'relation_delegate_class' for NilClass:Class嘗試加載user關系時NoMethodError: undefined method 'relation_delegate_class' for NilClass:Class

通過將user_type列更改為nil或正確的類名來進行足夠簡單的修復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM