【问题标题】:Couldn't find User without an ID, rails 4找不到没有 ID 的用户,rails 4
【发布时间】:2015-11-30 21:39:47
【问题描述】:

我有两种用户类型:艺术家和粉丝。我希望粉丝能够关注艺术家。到目前为止,跟随它们不起作用,但不跟随却可以。我有 createdestroy 设置相同的方式,但似乎无法让它工作。尝试create 关系时,我收到错误找不到没有 ID 的艺术家。无论如何我可以找到艺术家的 ID?

代码如下:

relationships_controller.rb

class RelationshipsController < ApplicationController

  before_action :authenticate_fan!

  def create
    @relationship = Relationship.new
    @relationship.fan_id = current_fan.id
    @relationship.artist_id = Artist.find(params[:id]).id #the error
    if @relationship.save
      redirect_to (:back)
    else
      redirect_to root_url
    end
  end

  def destroy
    current_fan.unfollow(Artist.find(params[:id]))
    redirect_to (:back)
  end

end

artists_controller.rb

def show
  @artist = Artist.find(params[:id])
end

艺术家/show.html.erb

<% if fan_signed_in? && current_fan.following?(@artist) %>
  <%= button_to "unfollow", relationship_path, method: :delete, class: "submit-button" %>
<% elsif fan_signed_in? %>
  <%= form_for(Relationship.new, url: relationships_path) do |f| %>
    <%= f.submit "follow", class: "submit-button" %>
  <% end %>
<% end %>

models/fan.rb

has_many :relationships, dependent: :destroy
has_many :artists, through: :relationships
belongs_to :artist

def following?(artist)
  Relationship.exists? fan_id: id, artist_id: artist.id
end

def unfollow(artist)
  Relationship.find_by(fan_id: id, artist_id: artist.id).destroy
end

models/artists.rb

has_many :relationships, dependent: :destroy
has_many :fans, through: :relationships
belongs_to :fan

routes.rb

resources :relationships, only: [:create, :destroy]

【问题讨论】:

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


    【解决方案1】:

    基本上,您需要向操作发送artist_id。将您的 form 更改为此。需要进行大量重构,但这个对您有用:

    <%= form_for(Relationship.new, url: relationships_path) do |f| %>
      <%= hidden_field_tag :artist_id, @artist.id %>
      <%= f.submit "follow", class: "submit-button" %>
    <% end %>
    

    在控制器中,您可以像这样访问它:

    @relationship.artist_id = Artist.find(params[:artist_id]).id
    

    【讨论】:

      【解决方案2】:

      我会考虑用嵌套路由来解决这个问题:

      resources :artists, shallow: true do
        resources :relationships, only: [:create, :destroy]
      end
      

      这将在艺术家的常规 CRUD 路线之外创建这些路线:

                    Prefix Verb   URI Pattern                                 Controller#Action
      artist_relationships POST   /artists/:artist_id/relationships(.:format) relationships#create
              relationship DELETE /relationships/:id(.:format)                relationships#destroy
      

      请注意,我们使用 shallow: true 来限定 /artists/:artist_id 下的创建路由,而不是销毁路由。

      然后您可以更改表单:

      <%= form_for(Relationship.new, url: artist_relationships_path(artist_id: @artist)) do |f| %>
        <%= f.submit "follow", class: "submit-button" %>
      <% end %>
      

      还有你的控制器:

      class RelationshipsController < ApplicationController
      
        before_action :authenticate_fan!
      
        def create
          current_fan.relationships.build(artist: Artist.find(params[:artist_id]))
          if @relationship.save
            redirect_to(:back)
          else
            redirect_to root_url # makes more sense to redirect back to @artist ?
          end
        end
      
        def destroy
          @relationship = current_fan.relationships.find(params[:id])
          @relationship.destroy
          redirect_to(:back)
          # or redirect back to the artist page.
          # redirect_to @relationship.artist
        end
      end
      

      请注意我们如何重构销毁操作 - 您永远不希望有一个带有 :id 参数的路由指向一个完全不同的资源。那只是糟糕的 REST 设计。如果我们知道关系的 ID,我们甚至不需要知道艺术家 ID。相反,这里的 ID 指的是关系资源。

      要创建一个链接来破坏你会做的关系:

      <%= link_to 'Unfollow', relationship_path(@relationship), method: :delete %>
      

      让我们摆脱@​​987654328@ 方法。

      我们可以修复Fan#following? 方法。

      def following?(artist)
        relationships.exists?(artist: artist)
      end
      

      通过使用关系(在 ActiveRecord 的意义上!)而不是直接查询关系模型,您可以使用预先加载来避免额外的查询,而且您不必指定风扇。

      【讨论】:

      • 移除 redirect_to :back 调用
      猜你喜欢
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-24
      • 1970-01-01
      • 2013-03-11
      相关资源
      最近更新 更多