如何让UsersPublisher连接模型工作

时间:2016-01-10 12:18:52

标签: ruby-on-rails database postgresql join many-to-many

我有三个模型:User,Publisher和Interest,它们都有通过三个连接模型链接的多对多关系,但只有2个连接模型中的2个记录了它们的2个父模型的id。我的UsersPublisher模型不会将User链接到Publisher。

我的兴趣控制器会处理一个表单(请参阅代码),我要求用户提供兴趣和发布者。后者通过fields_for方法处理,允许您通过InterestsController传递Publisher属性。 UsersPublisher连接模型记录user_id,但publisher_id为nil。

我尝试将@users_publishers放在Publishers-和InterestsController的new和create方法中。我在InterestsController中使用after_action的最新尝试(参见代码)也失败了。我也尝试过PublishersController中的after_action方式

非常感谢您的帮助!

UsersPublisher连接模型

class UsersPublisher < ActiveRecord::Base
  belongs_to :user
  belongs_to :publisher
end

InterestsController

class InterestsController < ApplicationController
before_action :find_user
after_action  :upublisher, only: [:new]

  def index
  @interests = policy_scope(Interest)
end

def show
  @interest = Interest.find(params[:id])
end

def new
@interest = Interest.new
@interest.publishers.build
authorize @interest
end

def create
  @interest = Interest.new(interest_params)
  @users_interests = UsersInterest.create(user: current_user, interest: @interest)
  authorize @interest
    if @interest.save
      respond_to do |format|
        format.js
        format.html {redirect_to root_path}
        end
        flash[:notice] = 'Thank you, we will be in touch soon'
    else
      respond_to do |format|
        format.js { render }
        format.html { render :new }
      end
  end
end

def edit
  @interest = Interest.find(params[:id])
  authorize @interest
end

def update
  @interest = Interest.find(params[:id])
  @interest.update(interest_params)
  if @interest.save
    flash[:notice] = 'Your interest has been added'

  else
    flash[:notice] = 'Oops something went wrong'
  end
end

private

  def interest_params
    params.require(:interest).permit(:name, publishers_attributes: [:publisher,:id, :feed])
  end

  def find_user
    @user = current_user
  end

def upublisher
   @users_publishers = UsersPublisher.create(publisher: @publisher, user: current_user)
end

end

表格

 <%= form_for [@user, @interest] do |f| %>
    <%= f.label :name %>
    <%= f.text_field :name %>

    <%= f.fields_for :publishers do |ff| %>
     <%= ff.label :publisher %>
     <%= ff.text_field :publisher %>
     <%= ff.label :feed %>
     <%= ff.text_field :feed %>
   <%end%>
  <%= f.submit "Submit" %>

<%end%>

1 个答案:

答案 0 :(得分:0)

由于您使用的是fields_for,因此您需要确保拥有accepts_nested_attributes_for

class UsersPublisher < ActiveRecord::Base
  belongs_to :user
  belongs_to :publisher
  accepts_nested_attributes_for :publisher
end

这应该可以解决您的问题(如果您按照概述的那样)。

您的问题相当广泛,所以我不知道上述内容是否有效。以下是我的笔记......

从外观上看,你的结构非常复杂;你应该努力使它尽可能简单。在创建“兴趣”的情况下,您可能希望完全摆脱该形式:

#config/routes.rb
resources :publishers do
   resources :interests, path: "interest", only: [:create, :destroy] #-> url.com/publishers/:publisher_id/interest
end

#app/controllers/interests_controller.rb
class InterestsController < ApplicationController
   before_action :set_publisher

   def create
      current_user.interests.create publisher: @publisher
   end

   def destroy
      @interest = current_user.interests.find_by publisher_id: @publisher.id
      current_user.interests.delete @interest
   end

   private

   def set_publisher
      @publisher = UserPublisher.find params[:publisher_id]
   end

end

您可以按如下方式使用上述内容:

<%= link_to "Add Interest", publisher_interest_path(@publisher), method: :post %>
<%= link_to "Remove Interest", publisher_interest_path(@publisher), method: :delete %>

正确地思考它,你的结构非常糟糕。

我会做这样的事情:

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :interests
   has_many :publishers, through: :interests
end

#app/models/interest.rb
class Interest < ActiveRecord::Base
   belongs_to :user
   belongs_to :publisher
   accepts_nested_attributes_for :publisher
end

#app/models/publisher.rb
class Publisher < ActiveRecord::Base
   has_many :interests,
   has_many :users, through: :interests
end

这可以让您为任意数量的interestsusers创建publishers。如果您为特定用户创建publisher,则可以使用accepts_nested_attributes_for传递相应的数据:

#config/routes.rb
resources :users do
   resources :interest, only: [:new, :create, :destroy] #-> url.com/users/:user_id/interests/new
end

#app/controllers/interests_controller.rb
class InterestsController < ApplicationController
   def new
      @user     = User.find params[:user_id]
      @interest = @user.interests.new 
      @interest.publisher.build
   end

   def create
      @user     = User.find params[:user_id]
      @interest = @user.interests.new interest_params
   end

   private

   def interest_params
      params.require(:interest).permit(:user, :publisher)
   end
end 

#app/views/interests/new.html.erb
<%= form_for [@user, @interest] do |f| %>
   <%= f.fields_for :publisher do |p| %>
      <%= p.text_field :name %>
   <% end %>
   <%= f.submit %>
<% end %>