地址:类的未定义方法`model_name'

时间:2014-08-07 17:07:22

标签: ruby-on-rails ruby ruby-on-rails-3 orm ruby-on-rails-3.2

我没有在我的应用程序中使用ActiveRecord作为ORM,而是使用jgaskins(https://github.com/jgaskins/perpetuity)的Perpetuity gem。当我尝试显示地址#index页面时,我收到错误' undefined方法' model_name for Address:Class。 这是我的模特

 class Address
   attr_accessor :city, :county, :line1, :line2, :postcode
 end

我的控制器:

class AddressesController < ApplicationController

  def index
    @addresses = Perpetuity[Address].all
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @addresses }
    end
  end

  def show
    @address = Perpetuity[Address].find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @address }
    end
  end
  def new
    @address = Address.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @address }
    end
  end

  def edit
    @address = Perpetuity[Address].find(params[:id])
  end

  def create
    @address = Address.new(params[:address])
    Perpetuity[Address].insert @address

    respond_to do |format|
      if @address.save
        format.html { redirect_to @address, notice: 'Address was successfully created.' }
        format.json { render json: @address, status: :created, location: @address }
      else
        format.html { render action: "new" }
        format.json { render json: @address.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    @address = Perpetuity[Address].find(params[:id])

    respond_to do |format|
      if @address.update_attributes(params[:address])
        format.html { redirect_to @address, notice: 'Address was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @address.errors, status: :unprocessable_entity }
      end
    end
  end

 def destroy
   @address = Perpetuity[Address].find(params[:id])
   Perpetuity[Address].delete @address

   respond_to do |format|
     format.html { redirect_to addresses_url }
     format.json { head :no_content }
   end
 end
end

地址/ index.html.erb文件     

列出地址

<table>
  <tr>
    <th>Line1</th>
    <th>Line2</th>
    <th>Postcode</th>
    <th>City</th>
    <th>County</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @addresses.each do |address| %>
  <tr>
    <td><%= address.line1 %></td>
    <td><%= address.line2 %></td>
    <td><%= address.postcode %></td>
    <td><%= address.city %></td>
    <td><%= address.county %></td>
    <td><%= link_to 'Show', address %></td>

    <td><%= link_to 'Edit', edit_address_path(address) %></td>
    <td><%= link_to 'Destroy', address, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New Address', new_address_path, class: "tiny button radius" %>

我尝试过在stackoverflow上描述的不同解决方案,包括将以下代码添加到控制器(undefined method `model_name' for Project:Class):

 extend ActiveModel::Naming
 include ActiveModel::Conversion
 def persisted?
   false
 end

然而,这会导致另一个错误:

Routing Error

No route matches {:action=>"edit", :controller=>"addresses", :id=>#<Address:0x52f8df8 @id="23983a22-2603-4f9b-a8b6-9fe3e53eba39", @line1=nil, @line2=nil, @postcode=nil, @city="Budapest", @county=nil, @created_at=nil, @updated_at=nil>}
Try running rake routes for more information on available routes.

对于某些人来说,整个对象被读作id。有谁知道如何使这个工作?谢谢。

1 个答案:

答案 0 :(得分:1)

根据Perpetuity README文档,您必须在对象中包含要传递给各种Rails方法的ActiveModel :: Model(例如redirect_to,form_for和render)。“

试试这个,它应该按预期工作:

class Address
 attr_accessor :city, :county, :line1, :line2, :postcode
 include Perpetuity::RailsModel
end

再次来自自述文件“这将让Rails知道如何以Perpetuity处理它们的方式与您的模型交谈。”

model_name是一种ActiveModel方法,因此如果不包含此方法,您将无法正确访问这些方法并相信我很多rails gems使用model_name来处理与路由相关的情况。

更新

这是基于errors方法

的评论问题

我在errors的任何地方都没有看到Perpetuiy方法。我认为你必须为此实现自己的结构。

同样save不会返回false,只是在没有验证的情况下更新属性,因此您可能需要重新考虑您的设计。

实际上在1.0.0.0beta中完全删除了更改日志验证

就像你说你包括ActiveModel::Errors,你可能会像这样处理。

def errors
  @errors ||= ActiveModel::Errors.new(self) 
end 

def save 
  validate! 
  errors.empty? ? super : false
end 

def validate!
 #place custom validations here e.g.
 errors.add(:name, "cannot be blank.") if self.name = ""
 errors.add(:number,"must be less than 7.") if self.number >= 7
end

请注意,自定义验证不会是标准的Rails验证,因为这些验证也不包括在内,如果您继续沿着包含路径向下移动,您最终会回到ActiveRecord

另请注意我没有并且没有使用Perpetuity所以这些是准则,我没有表示他们将100%正确地工作