在 Rails 4 中出现未定义的方法错误

Getting An Undefined Method Error in Rails 4

我正在使用回形针 & Rails 4,但在访问我的画廊索引页时出现此错误。

错误如下:

我的索引页代码是这样的:

<h3> for <%= Property.name %></h3>

<table>
  <thead>
    <tr>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @galleries.property.each do |gallery| %>
      <tr>
        <td><%= link_to 'Show', property_gallery_path(params[:property_id], gallery) %></td>
        <td><%= link_to 'Edit', edit_property_gallery_path(params[:property_id], gallery) %></td>
        <td><%= link_to 'Destroy', property_gallery_path(params[:property_id], gallery), method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

我的画廊控制器页面是这个

 class GalleriesController < ApplicationController
  before_action :set_imageable
  before_action :set_property, only: [:show, :edit, :update, :destroy]
  before_action :set_gallery, only: [:show, :edit, :update, :destroy]

  # GET /galleries
  # GET /galleries.json
  def index
    @galleries = Gallery.all
  end

  # GET /galleries/1
  # GET /galleries/1.json
  def show
  end

  # GET /galleries/new
  def new
    @gallery = Gallery.new
  end

  # GET /galleries/1/edit
  def edit
  end

  # POST /galleries
  # POST /galleries.json
  def create
    @gallery = @imageable.galleries.new(gallery_params)


    respond_to do |format|
      if @gallery.save

        if params[:images]
          params[:images].each { |image|
            @gallery.pictures.create(image: image)
          }
        end

        format.html { redirect_to @imageable, notice: 'Gallery was successfully created.' }
        format.json { render :show, status: :created, location: @gallery }
      else
        format.html { render :new }
        format.json { render json: @gallery.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /galleries/1
  # PATCH/PUT /galleries/1.json
  def update
    respond_to do |format|
      if @gallery.update(gallery_params)
        format.html { redirect_to property_gallery_path, notice: 'Gallery was successfully updated.' }
        format.json { render :show, status: :ok, location: @gallery }
      else
        format.html { render :edit }
        format.json { render json: @gallery.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /galleries/1
  # DELETE /galleries/1.json
  def destroy
    @gallery.destroy
    respond_to do |format|
      format.html { redirect_to galleries_url, notice: 'Gallery was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_gallery
      @gallery = Gallery.find(params[:id])
    end

    def set_property
      @property = Property.find(params[:id])
    end

    def set_imageable
      klass = [Property, Space].detect { |c| params["#{c.name.underscore}_id"]}
      puts "Klass is #{klass.inspect}"
      @imageable = klass.find(params["#{klass.name.underscore}_id"])
      puts "Imageable is #{@imageable.inspect}"
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def gallery_params
      params.permit(:gallery)
    end


end

现在考虑之后,我去了我的画廊控制器并查看了索引行。那里有一个 @galleries = Gallery.all,它当然会拉取与 属性 相关的所有画廊。我知道它正在拉动与 属性 相关的所有画廊,因为我有 before_action :set_property 和 before_action :set_gallery.

我想知道无方法错误是否与 属性 的设置方式有关。我不确定。但是我的 property_id 在我的请求参数中被设置为“1”。所以价值在传递。

我明显遗漏了什么吗?而且我通常以正确的方式思考这个问题?

这是我的全部 galleries_controller.rb

    class GalleriesController < ApplicationController
  before_action :set_imageable
  before_action :set_property, only: [:index, :show, :edit, :update, :destroy]
  before_action :set_gallery, only: [:show, :edit, :update, :destroy]

  # GET /galleries
  # GET /galleries.json
  def index
    @galleries = @property.galleries
  end

  # GET /galleries/1
  # GET /galleries/1.json
  def show
  end

  # GET /galleries/new
  def new
    @gallery = Gallery.new
  end

  # GET /galleries/1/edit
  def edit
  end

  # POST /galleries
  # POST /galleries.json
  def create
    @gallery = @imageable.galleries.new(gallery_params)


    respond_to do |format|
      if @gallery.save

        if params[:images]
          params[:images].each { |image|
            @gallery.pictures.create(image: image)
          }
        end

        format.html { redirect_to @imageable, notice: 'Gallery was successfully created.' }
        format.json { render :show, status: :created, location: @gallery }
      else
        format.html { render :new }
        format.json { render json: @gallery.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /galleries/1
  # PATCH/PUT /galleries/1.json
  def update
    respond_to do |format|
      if @gallery.update(gallery_params)
        format.html { redirect_to property_gallery_path, notice: 'Gallery was successfully updated.' }
        format.json { render :show, status: :ok, location: @gallery }
      else
        format.html { render :edit }
        format.json { render json: @gallery.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /galleries/1
  # DELETE /galleries/1.json
  def destroy
    @gallery.destroy
    respond_to do |format|
      format.html { redirect_to galleries_url, notice: 'Gallery was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_gallery
      @gallery = Gallery.find(params[:id])
    end

    def set_property
      @property = Property.find(params[:id])
    end

    def set_imageable
      klass = [Property, Space].detect { |c| params["#{c.name.underscore}_id"]}
      puts "Klass is #{klass.inspect}"
      @imageable = klass.find(params["#{klass.name.underscore}_id"])
      puts "Imageable is #{@imageable.inspect}"
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def gallery_params
      params.permit(:gallery)
    end


end

@galleries 是复数形式——基本上是画廊对象的数组,因此您不能直接在其上调用方法。您需要遍历每个对象,然后在单个对象上调用该方法。

您可以通过以下方式实现类似的目的:

<tbody>
  <% @galleries.each do |gallery| %>
    <tr>
      <td><%= link_to 'Show', property_gallery_path(params[:property_id], gallery) %></td>
      <td><%= link_to 'Edit', edit_property_gallery_path(params[:property_id], gallery) %></td>
      <td><%= link_to 'Destroy', property_gallery_path(params[:property_id], gallery), method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
</tbody>

首先

   @galleries = Gallery.all

将 return 所有画廊,无论 属性

如果您想为任何 属性 获取画廊,请执行此操作

@galleries = @property.galleries

其次,您无法从画廊中获取单个 属性,因为画廊是您在此处执行的数组

<% @galleries.property.each do |gallery| %>

你需要做

<% @galleries.each do |gallery| %>
 <%property = gallery.property %>
 #what you want to do
<% end %>

同时更新您的 before_action

 before_action :set_property, only: [:index, :show, :edit, :update, :destroy]

并改变这个

def set_property
  @property = Property.find(params[:id])
end

def set_property
  @property = Property.find(params[:property_id])
end