【问题标题】:Rails 4: Accessing model through anotherRails 4:通过另一个访问模型
【发布时间】:2014-06-21 01:56:20
【问题描述】:

我无法访问图片模型设置,例如:

请求has_one图库has_many图片

从 Request 模型的显示视图中,我需要访问其 Gallery 的图片,它给了我错误 undefined method 'pictures' for nil:NilClass。

型号:

class Request < ActiveRecord::Base
  belongs_to :user
  has_one :gallery
  has_many :pictures, through: :gallery
end

class Gallery < ActiveRecord::Base
  has_many :pictures, :dependent => :destroy
  belongs_to :request
end

class Picture < ActiveRecord::Base
  belongs_to :gallery
  has_attached_file :image,
    :path => ":rails_root/public/images/:id/:filename",
    :url  => "/images/:id/:filename"

  do_not_validate_attachment_file_type :image
end

请求控制器:

class RequestsController < ApplicationController
  before_action :set_request, only: [:show, :edit, :update, :destroy]

  def show
    @request  = Request.find(params[:id])
    @gallery = @request.gallery
    @pictures = @gallery.pictures
  end

  def new
    @request = Request.new
    @gallery = Gallery.new(params[:request_id])
    @gallery = @request.gallery
    @pictures = @gallery.pictures
  end

  def create
    @request = Request.new(request_params)

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


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

    # Never trust parameters from the scary internet, only allow the white list through.
    def request_params
        params.require(:request).permit(:title, :description, :username, gallery_attributes: [:id, :name, :description]).merge(user_id: current_user.id)
    end
end

画廊控制器:

class GalleriesController < ApplicationController

  def show
    @gallery  = Gallery.find(params[:id])
    @pictures = @gallery.pictures

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @gallery }
    end
  end

  def new
    @gallery = Gallery.new

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

  def create
    @gallery = Gallery.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 @gallery, notice: 'Gallery was successfully created.' }
        format.json { render json: @gallery, status: :created, location: @gallery }
      else
        format.html { render action: "new" }
        format.json { render json: @gallery.errors, status: :unprocessable_entity }
      end
    end
  end

  def gallery_params
      params.require(:gallery).permit(:name, :description, :cover, :token)
  end
end

图片控制器:

class PicturesController < ApplicationController

  def show
    @picture = Picture.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @picture }
    end
  end


  def new
    @gallery = Gallery.find(params[:gallery_id])
    @picture = @gallery.pictures.build

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

  def create
    @picture = Picture.new(params[:picture])

    if @picture.save
      respond_to do |format|
        format.html {
          render :json => [@picture.to_jq_upload].to_json,
          :content_type => 'text/html',
          :layout => false
        }
        format.json {
          render :json => [@picture.to_jq_upload].to_json
        }
      end
    else
      render :json => [{:error => "custom_failure"}], :status => 304
    end
  end

请求显示视图: (缩短)

<%- model_class = Request -%>
    <% unless @pictures.empty? %>
        <% @pictures.each do |pic| %>
            <li class="span3" id="picture_<%= pic.id %>">
              <div class="thumbnail">
                <%= image_tag pic.image.url %>
                <div class="caption">                       
                </div>
              </div>
            </li>
        <% end %>
    <% end %>

在请求显示视图中,我正在尝试访问@pictures,它应该会为我提供请求图库的所有图片。我讨厌发布这么多代码,但我对此很陌生,不想遗漏任何东西。有什么想法吗?

【问题讨论】:

  • 您收到该错误的原因是因为 @request.gallery 返回 null,这意味着您的 request 没有与之关联的 gallery。
  • 你知道我能做些什么来解决这个问题吗?当我创建一个请求时,我以为我的请求控制器正在创建它。

标签: ruby-on-rails activerecord ruby-on-rails-4 actioncontroller


【解决方案1】:

这部分有很大的问题:

def show
  @request  = Request.find(params[:id])
  @gallery = @request.gallery
  @pictures = @gallery.pictures
end

def new
  @request = Request.new
  @gallery = Gallery.new(params[:request_id])
  @gallery = @request.gallery
  @pictures = @gallery.pictures
end

在show 中,您需要检查请求是否具有图库(如果您没有在关联上添加验证,您可以这样做:Request 模型中的validates_presence_of :gallery)。另一种方法是添加 nil 检查:

 def show
  @request  = Request.find(params[:id])
  unless @request.gallery.nil?
    @gallery = @request.gallery
    @pictures = @gallery.pictures
  end
end

但是如果你期望这个模型,添加关联:

class Request < ActiveRecord::Base
  belongs_to :user
  has_one :gallery
  validates_presence_of :gallery
  has_many :pictures, through: :gallery
end

另外,在新操作中,只需创建 @request,没有与之关联的画廊。您还定义了@gallery 2 次,我不知道原因。你可以构建它:

def new
  @request = Request.new
  @gallery = @request.build_gallery
  @pictures = @gallery.pictures
end

我也无法理解params[:request_id] 是什么。如果它是新的请求你已经有什么 id?

更新

我现在可以看到,您只需更改 new 操作即可。

def new
  @request = Request.new
end

【讨论】:

  • 感谢您的帮助。我意识到我的代码一团糟,我只是在试验,因为我无法找出问题所在。我应该明确的是,我需要在创建请求时创建一个画廊,以便我可以以一种形式使用两者。你知道我该怎么做吗?
  • 是的,@request.build_gallery 正是这样做的,但你必须向它发送一些参数,你应该在 create 操作中这样做。将只有@request = Request.new request_params,其中request_params 将包含画廊参数并自动分配它。
  • 再次感谢zishe,终于成功了。你教会了我很好。神速。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
相关资源
最近更新 更多