Ruby on rails 多态性和有一个关联

Ruby on rails 多态性和有一个关联,ruby-on-rails,ruby,Ruby On Rails,Ruby,我已经在我的应用程序中设置了多态关联。图片既属于记分板模型,也属于用户模型。每个记分板和用户都有一张图片。我还有嵌套的路由,其中图片资源嵌套在用户和记分板资源中 为用户路由文件: resources :users do resources :picture end resources :account_activations, only: [:edit] resources :password_resets, only: [:new, :create, :edit, :update] r

我已经在我的应用程序中设置了多态关联。图片既属于记分板模型,也属于用户模型。每个记分板和用户都有一张图片。我还有嵌套的路由,其中图片资源嵌套在用户和记分板资源中

为用户路由文件:

resources :users do
  resources :picture
end

resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]

resources :conversations, only: [:index, :show, :destroy] do
  member do
    post :reply
    post :restore
    post :mark_as_read
  end

  collection do
    delete :empty_trash
  end
end
记分板的路由文件:

resources :scoreboards do 
  member do
    put :favourite
    get :deleteteams
    get :deleteschedules
  end

  resources :invitations, only: [:new, :create]
  resources :comments
  resources :teams, only: [:edit, :create, :destroy, :update]
  resources :schedules 
  resources :picture
end
我已经安装了一个图片控制器。代码如下所示

class PictureController < ApplicationController
  before_filter :load_pictureable

  def new 
    @picture = @pictureable.build_picture                              
  end                                               

  def create
  end

  def destroy
  end

  private

  def picture_params
    params.require(:picture).permit(:picture)
  end

  def load_pictureable
    klass = [User, Scoreboard].detect { |c| params["#{c.name.underscore}_id"] }
    @pictureable = klass.find(params["#{klass.name.underscore}_id"]) 
  end
end                           

我不知道为什么它会将我重定向到show动作,我想可能是嵌套路由。我不知道问题出在哪里。我以为通过传递以下URL
new\u scoreboard\u picture\u path
解决了这个问题。然而,当我按下上传照片,它会带我回到同一个网址。这是有意义的,因为我以新的形式显式地声明URL。然而,这是不正确的。如果有人能帮我找出问题所在,那将是一个很大的帮助。我只包含了相关代码。但是,如果我遗漏了什么,请务必让我知道。任何关于我为什么会出现这个错误的解释都会澄清我的思考过程。这是第一次使用多态关联。任何形式的帮助都会很好

我将使用继承和两个单独的控制器:

# the base controller
class PicturesController < ApplicationController
  before_action :load_pictureable

  def new 
    @picture = @pictureable.build_picture                              
  end                                               

  def create
    @picture = @pictureable.build_picture
    if @picture.save
      do_redirect
    else
      render_errors
    end
  end

  def destroy
    # ...
  end

  private

  def picture_params
    params.require(:picture).permit(:picture)
  end

  # Finds the picturable based on the module name of the class
  # for examples `Pets::PicturesController` will look for
  # Pet.find(params[:pet_id])
  def find_pictureable
    # this looks at the class name and extracts the module name
    model_name = self.class.deconstantize.singularize
    @pictureable = model_name.constanize.find(params["#{model_name}_id"])
  end

  # subclasses can override this to whatever they want
  def do_redirect
    redirect_to @pictureable
  end

  # subclasses can override this to whatever they want
  def render_errors
    render :new
  end
end
因为一个用户/记分板只能有一张图片,所以我们使用的是
资源
,而不是
资源
。这将为单个资源设置路由。使用
rake routes
查看差异。例如,使用
POST/users/:user\u id/picture
创建图片

然后,我们设置子控制器:

# app/controllers/users/pictures_controller.rb
class Users::PicturesController < PicturesController
end

 # app/controllers/scoreboards/pictures_controller.rb
class Scoreboards::PicturesController < PicturesController
end
将使用
users\u picture\u路径(user\u id:@pictureable.id)
或记分板使用相同的路径


我将使用继承和两个单独的控制器:

# the base controller
class PicturesController < ApplicationController
  before_action :load_pictureable

  def new 
    @picture = @pictureable.build_picture                              
  end                                               

  def create
    @picture = @pictureable.build_picture
    if @picture.save
      do_redirect
    else
      render_errors
    end
  end

  def destroy
    # ...
  end

  private

  def picture_params
    params.require(:picture).permit(:picture)
  end

  # Finds the picturable based on the module name of the class
  # for examples `Pets::PicturesController` will look for
  # Pet.find(params[:pet_id])
  def find_pictureable
    # this looks at the class name and extracts the module name
    model_name = self.class.deconstantize.singularize
    @pictureable = model_name.constanize.find(params["#{model_name}_id"])
  end

  # subclasses can override this to whatever they want
  def do_redirect
    redirect_to @pictureable
  end

  # subclasses can override this to whatever they want
  def render_errors
    render :new
  end
end
因为一个用户/记分板只能有一张图片,所以我们使用的是
资源
,而不是
资源
。这将为单个资源设置路由。使用
rake routes
查看差异。例如,使用
POST/users/:user\u id/picture
创建图片

然后,我们设置子控制器:

# app/controllers/users/pictures_controller.rb
class Users::PicturesController < PicturesController
end

 # app/controllers/scoreboards/pictures_controller.rb
class Scoreboards::PicturesController < PicturesController
end
将使用
users\u picture\u路径(user\u id:@pictureable.id)
或记分板使用相同的路径


请遵循中的rails控制器命名约定。您可以从浏览器中粘贴呈现的表单HTML代码吗?如果您还可以显示
routes.rb
code@Jay-ArPolidario我已经编辑了我的原始问题,并包含了记分板和用户的所有相关路由文件。也许你在
记分板\u图片\u路径中遗漏了新的
->?@Jay ArPolidario,我以前试过。它可以工作,但当我提交表单时,我会收到一个错误。当我尝试执行post请求时,URL不起作用。例如,如果我转到URL users/1/picture/new。它可以工作,但当我提交表单时,它会严格地将我带回新的记分板\图片\路径。请遵循rails控制器的命名约定。您可以从浏览器中粘贴呈现的表单HTML代码吗?如果您还可以显示
routes.rb
code@Jay-ArPolidario我已经编辑了我的原始问题,并包含了记分板和用户的所有相关路由文件。也许你在
记分板\u图片\u路径中遗漏了新的
->?@Jay ArPolidario,我以前试过。它可以工作,但当我提交表单时,我会收到一个错误。当我尝试执行post请求时,URL不起作用。例如,如果我转到URL users/1/picture/new。它是有效的,但是当我提交表单时,它严格地把我带回到NeXySmithBoAD.PigTrimePipe路径。我没有为简洁而添加它,但是你应该考虑清理步骤,在那里你删除孤立图片记录。我没有为简洁而添加它,但是你应该考虑清理步骤,在那里你删除孤立图片记录。
# app/controllers/users/pictures_controller.rb
class Users::PicturesController < PicturesController
end

 # app/controllers/scoreboards/pictures_controller.rb
class Scoreboards::PicturesController < PicturesController
end
<%= form_for([@pictureable, @picture], html: {multipart: true}) do |f| %>