本文介绍了轨道4:未定义的方法`relation_delegate_class'的模式:类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想按照这个$ C有关的的。

I am trying to follow this coderwall tutorial about Creating a Scoped Invitation System for Rails.

在我的Rails应用程序4,我有以下型号:

In my Rails 4 app, I have the following models:

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

下面是我的模型,并从本教程的模型之间的对应关系:

Here is the correspondance between my models and the models from the tutorial:

  • 用户&LT; => 用户
  • 日历&LT; => 用户组
  • 管理​​&LT; => 成员
  • 邀请&LT; => 邀请
  • User <=> User
  • Calendar <=> UserGroup
  • Administration <=> Membership
  • Invite <=> Invite

我现在是在制作一个新的邀请的部分:

  • 邀请模型已更新为 before_create 过滤器和 generate_token 方法。
  • 邀请控制器已经更新了创建操作。
  • The Invite model has been updated with the before_create filter and generate_token method.
  • The Invites controller has been updated with the create action.

然而,当我访问日历编辑视图填写邀请的形式,我得到以下错误:

However, when I visit the Calendar edit view to fill out the Invite form, I get the following error:

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 行。

---

更新:这里是我的邀请模式的内容:

UPDATE: here is the content of my Invite model:

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 :在this问题,作者解释这个问题可能来自CanCanCan&安培; Rolify。我不会用这些宝石,但是我用的权威人士。认为这将是我的问题的情况下是有用的。

UPDATE 2: in this question, the author explains the problem may come from CanCanCan & Rolify. I don't use these gems, but I use Pundit. Thought this would be useful in the context of my question.

---

更新3 :这里也是我用于迁移的邀请型号:

UPDATE 3: here is also the migration I used for the Invite model:

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 ,因为作用的一个给定的用户只存在于管理​​表中,对于给定的日历:如果:recipient_role 是PTED为 recipient.role 自动除$ P $用Rails的,那么也许这原因造成的错误?

I am wondering if the problem could be caused by the t.string :recipient_role, since the role of a given user only exist in the administration table, for a given calendar: if :recipient_role is automatically interpreted as recipient.role by Rails, then maybe this is causing the error?

---

更新4 :这里是CalendarsController的内容:

UPDATE 4: here is the content of 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 :这里的服务器日志:

UPDATE 5: here are the server logs:

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

邀请控制器:?可这是这里的问题的根源

in the Invites controller: could this be the root of the problem here?

---

什么这个错误讯息,以及如何解决这个问题?任何想法

Any idea about what this error message mean and how to fix the issue?

推荐答案

问题是棘手的识别,尤其是刚刚从问题的内容。

The problem was tricky to identify, especially just from the content of the question.

问题

THE PROBLEM

为什么我得到了未定义的方法'relation_delegate_class对于邀请的原因:类错误是因为邀请是不再被认为是一个模型的Rails。

The reason why I was getting the undefined method 'relation_delegate_class' for Invite:Class error is because Invite was no longer considered to be a model by Rails.

问题的根源

THE ROOT CAUSE OF THE PROBLEM

当我创建了邀请邮件,我跑轨道摹邮件邀请而不是轨道摹邮件InviteMailer

When I created the Invite mailer, I ran rails g mailer Invite instead of rails g mailer InviteMailer.

由于这个原因,邀请作为邮件覆盖邀请作为一种模式,因此一旦产生错误的方法被应用到邀请模型的实例。

Because of this, Invite as a mailer override Invite as a model, hence creating errors as soon as methods were applied to instances of the Invite model.

我们如何计算出来

HOW WE FIGURED IT OUT

我的一个朋友,谁是方式更经历了编程比我,通过调整 @invite = @ calendar.invites.build 行,这是发现的问题造成错误。

One of my friends, who is way more experienced with programming than I am, identified the problem by tweaking the @invite = @calendar.invites.build line that was causing the error.

这使我们最终运行 Invite.first 在轨控制台:尽管我们应该有任何的一个实例邀请类,或零,我们实际上得到了一个错误。

This led us to eventually run Invite.first in the rails console: while we should have got either an instance of the Invite class, or nil, we actually got an error.

由于。首先应该是对任何ActiveRecord模型的有效方法,我们认识到,邀请不是考虑是一个模型的Rails。

Since .first should be a valid method on any ActiveRecord model, we realized that Invite was not a considered to be a model by Rails.

我们如何固定它

HOW WE FIXED IT

一旦我们确定了问题,修复它是pretty的简单:

Once we had identified the issue, fixing it was pretty straightforward:

  • 我们改变了邀请邮件程序的名称由 invite.rb invite_mailer。 RB
  • 在最近改名 invite_mailer.rb 文件中,我们替换班邀请&LT; ApplicationMailer 类InviteMailer&LT; ApplicationMailer
  • We changed the name of the Invite mailer from invite.rb to invite_mailer.rb
  • In the newly renamed invite_mailer.rb file, we replaced class Invite < ApplicationMailer with class InviteMailer < ApplicationMailer

我希望这是很有用的其他堆栈溢出用户谁可能得到类似的 relation_delegate_class 错误。

I hope this can be useful to other Stack Overflow users who might get a similar relation_delegate_class error.

这篇关于轨道4:未定义的方法`relation_delegate_class'的模式:类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-20 17:21