2014-06-15 90 views
1

我试图让我的头绕过通过在rails中的替代控制器添加记录到连接表的最佳方式。通过两个不同的控制器在rails中创建连接表记录

我在我的应用程序中会有各种模型需要这个,但是在我将这个方法转录到其他人之前,我会先关注这两个模型,所以应该以此为例。我有一个VenueInterest模型,它们将通过VenuesInterests模型(它有一些额外的可选属性,因此不是HABTM关系)连接。用户可以管理Venue实例和/或Interest实例,因此应该有能力选择附加到兴趣的场所,并且同样需要附加到场所的兴趣。这应该通过Interest实例视图上的Add Venues链接和Venue实例视图上的Add Interests链接完成。然后,这会让用户看到相关实例的列表,以选择他们想要选择的实例。

这里是我的模型:

Venue.rb

class Venue < ActiveRecord::Base 


has_many :interests, through: :venue_interests 
    has_many :venues_interests, dependent: :destroy 

    accepts_nested_attributes_for :venues_interests, :allow_destroy => true 

end 

Interest.rb

class Interest < ActiveRecord::Base 

has_many :venues, through: :venue_interests 
    has_many :venues_interests, dependent: :destroy 

end 

VenuesInterests.rb

class VenuesInterest < ActiveRecord::Base 

    belongs_to :interest 
belongs_to :venue 
validates :interest_id, presence: true 
validates :venue_id, presence: true 

end 

这一切似乎很好,但是它的继续滚筒和我正在努力的意见。我尝试在VenuesInterests控制器中添加一个额外的方法add_interest来完成VenuesInterests控制器中的创建方法的工作,以便在向场所添加场所时将会有不同的观点,否则我不知道我会如何做到这一点。我现在的场地控制器如下:

VenuesController.rb:

class VenuesController < ApplicationController 
before_filter :authenticate_knocker!, only: [:new, :edit, :create, :update, :destroy] 

respond_to :html, :json 

def index 
    @venues = Venue.all.paginate(page: params[:page]).order('created_at DESC') 
end 

def show 
    @venue = Venue.find(params[:id]) 
    @hash = Gmaps4rails.build_markers(@venue) do |venue, marker| 
     marker.lat venue.latitude 
     marker.lng venue.longitude 
     marker.infowindow venue.name 
    end 
end 

def new 
    @venue = Venue.new 
end 

def edit 
    @venue = Venue.find(params[:id]) 
end 

def create 
    @venue = current_knocker.venues.create(venue_params) 
    respond_to do |format| 
     if @venue.save! 
      format.html { redirect_to @venue, notice: 'Venue was successfully created.' } 
      format.json { render json: @venue, status: :created, location: @venue } 
     else 
      format.html { render action: "new" } 
      format.json { render json: @venue.errors, status: :unprocessable_entity } 
     end 
    end 
end 

def update 
    @venue = Venue.find(params[:id]) 
    @venue.update_attributes(venue_params) 
    respond_to do |format| 
     if @venue.update_attributes(venue_params) 
      format.html { redirect_to(@venue, :notice => 'Your Venue was successfully updated.') } 
      format.json { respond_with_bip(@venue) } 
     else 
      format.html { render :action => "edit" } 
      format.json { respond_with_bip(@venue) } 
     end 
    end 
end 

def destroy 
end 

def add_interests 
    @venues_interests = VenuesInterest.new 
    @interests = Interests.all.paginate(page: params[:page]).order(:name) 
end 

private 

def venue_params 
    params.require(:venue).permit(:admin... etc) 
end 

end 

当前不工作,我不知道如何在控制器中引用其他类,但最重要的事情我”我想知道的是有没有更好的方法来做到这一点,或者我是否正确(正确)?如果任何人有一个好的方法(也许是一个jQuery插件)允许多个选择实例的视图,那也会很棒!

+1

你的更新方法是打开权限提升:'@venue = Venue.find(PARAMS [:编号])' - >'current_knocker.venues.find(PARAMS [:ID ])' –

+0

如果你正确建立你的表单,你应该有'params [:venue] [:interest_ids]',然后,如果你更新你的venue_params以允许':interest_ids => []',那么它将分配兴趣到场地。在前端,这将涉及多选(见[选择](http://harvesthq.github.io/chosen/))。 –

+0

选择似乎是一个很好的选择,但我真正想要显示一个化身和一个模型的细节(即兴趣)的能力,所以将需要加载一个新的选择页面,可能成为一个模式。最好的方法是在'add_interest.html.erb'视图中包含一个表单并呈现部分列表,然后在Venue控制器中使用add_interest方法? –

回答

0

在我看来,我会利用现有的update方法来增加Interest和Venue之间的关系。我可以这样做:

def update 
    @venue = Venue.find(params[:id]) 
    @venue.update_attributes(params[:venue_params]) 
    if params[:interest_ids].present? 
     @venue.interests = Interest.where(id: params[:interest_ids]) 
     @venue.save 
    end 
    #more code to handle the rendering 
end 
+0

然后我会保留视图的add_interests.html.erb吗?如果是这样,我如何将这与更新方法联系起来? –

+0

终于研究出如何正确实现这一点。对于任何人,请尝试[此链接](http:// stackoverflow。COM /问题/ 8826407 /导轨-3多选,用,有一对多贯通协会)。 –

相关问题