简体   繁体   English

ruby on rails has_many通过关系

[英]ruby on rails has_many through relationship

Hi i'm having a little trouble with a has_many through relationship for my app and was hoping to find some help. 嗨,我在与has_many通过应用程序建立关系时遇到了一些麻烦,希望能找到一些帮助。 So i've got Users & Lectures. 所以我有用户和讲座。 Lectures are created by one user but then other users can then "join" the Lectures that have been created. 讲座由一个用户创建,但其他用户随后可以“加入”已创建的讲座。 Users have their own profile feed of the Lectures they have created & also have a feed of Lectures friends have created. 用户拥有自己创建的讲座的个人资料供稿,也有朋友创建的讲座的供稿。 This question however is not about creating a lecture but rather "Joining" a lecture that has been created already. 但是,此问题不是关于创建演讲,而是“加入”已经创建的演讲。 I've created a "lecturerelationships" model & controller to handle this relationship between Lectures & the Users who have Joined (which i call "actives"). 我创建了一个“演讲关系”模型和控制器,以处理演讲与已加入用户(我称之为“活动”)之间的这种关系。 Users also then MUST "Exit" the Lecture (either by clicking "Exit" or navigating to one of the header navigation links). 然后,用户还必须“退出”演讲(通过单击“退出”或导航到标题导航链接之一)。 I'm grateful if anyone can work through some of this with me... 如果有人能与我一起完成这一工作,我将不胜感激。

I've got: Users.rb model Lectures.rb model Users_controller Lectures_controller 我有:Users.rb模型Lectures.rb模型Users_controller Lectures_controller

then the following model 然后下面的模型

lecturerelationship.rb 讲义关系

class lecturerelationship < ActiveRecord::Base
  attr_accessible :active_id, :joinedlecture_id

  belongs_to :active, :class_name => "User"
  belongs_to :joinedlecture, :class_name => "Lecture"

  validates :active_id, :presence => true
  validates :joinedlecture_id, :presence => true

end

lecturerelationships_controller.rb LessonRelationships_controller.rb

class LecturerelationshipsController < ApplicationController
  before_filter :signed_in_user

  def create
   @lecture = Lecture.find(params[:lecturerelationship][:joinedlecture_id])
   current_user.join!(@lecture)
   redirect_to @lecture
  end

 def destroy
  @lecture = Lecturerelationship.find(params[:id]).joinedlecture
  current_user.exit!(@user)
  redirect_to @user
 end

end

Lectures that have been created (by friends) show up on a users feed in the following file (由朋友创建的)讲座显示在以下文件的用户供稿中

_activity_item.html.erb _activity_item.html.erb

<li id="<%= activity_item.id %>">
  <%= link_to gravatar_for(activity_item.user, :size => 200), activity_item.user %><br   clear="all">
  <%= render :partial => 'shared/join', :locals => {:activity_item => activity_item} %>
  <span class="title"><%= link_to activity_item.title, lecture_url(activity_item)  %></span><br clear="all">
  <span class="user">
   Joined by <%= link_to activity_item.user.name, activity_item.user %>
  </span><br clear="all">
  <span class="timestamp">
   <%= time_ago_in_words(activity_item.created_at) %> ago.
  </span>
  <% if current_user?(activity_item.user) %>
    <%= link_to "delete", activity_item, :method => :delete,
                                     :confirm => "Are you sure?",
                                     :title => activity_item.content %>
  <% end %>
</li>

Then you see I link to the the 'shared/join' partial above which can be seen in the file below 然后您会看到我链接到上面的“ shared / join”部分,可以在下面的文件中看到

_join.html.erb _join.html.erb

<%= form_for(current_user.lecturerelationships.build(:joinedlecture_id =>  activity_item.id)) do |f| %>
  <div>
   <%= f.hidden_field :joinedlecture_id %>
  </div>
  <%= f.submit "Join", :class => "btn btn-large btn-info" %>
<% end %>

Some more files that might be needed: 可能需要更多文件:

config/routes.rb config / routes.rb

SampleApp::Application.routes.draw do
  resources :users do
    member do
    get :following, :followers, :joined_lectures
  end
end

resources :sessions, :only => [:new, :create, :destroy]
resources :lectures, :only  => [:create, :destroy, :show]
resources :relationships, :only => [:create, :destroy] #for users following each other
resources :lecturerelationships, :only => [:create, :destroy] #users joining existing lectures

So what happens is the lecture comes in my activity_feed with a Join button option at the bottom...which should create a lecturerelationship of an "active" & "joinedlecture" (which obviously are supposed to be coming from the user & lecture classes. But the error i get when i click the join button is as follows: 因此,发生的情况是该讲座进入我的activity_feed中,并在底部带有“加入”按钮选项...这将创建“活动”和“联合讲座”(显然应该来自用户和讲座类)之间的讲座关系。但是当我单击加入按钮时出现的错误如下:

ActiveRecord::StatementInvalid in LecturerelationshipsController#create

SQLite3::ConstraintException: constraint failed: INSERT INTO "lecturerelationships"     ("active_id", "created_at", "joinedlecture_id", "updated_at") VALUES (?, ?, ?, ?)

Also i've included my user model (seems the error is referring to it) user.rb 我也包括了我的用户模型(似乎错误是指它)user.rb

class User < ActiveRecord::Base
  attr_accessible :email, :name, :password, :password_confirmation
  has_secure_password
  has_many :lectures, :dependent => :destroy


  has_many :lecturerelationships, :foreign_key => "active_id", :dependent => :destroy
  has_many :joined_lectures, :through => :lecturerelationships, :source =>    :joinedlecture

  before_save { |user| user.email = email.downcase }
  before_save :create_remember_token

  validates :name, :presence => true, :length => { :maximum => 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, :presence => true,
        :format => { :with => VALID_EMAIL_REGEX },
        :uniqueness => { :case_sensitive => false }
  validates :password, :presence => true, :length => { :minimum => 6 }
  validates :password_confirmation, :presence => true

  def activity
    # This feed is for "My Activity" - basically lectures i've started
    Lecture.where("user_id = ?", id)
  end

  def friendactivity
     Lecture.from_users_followed_by(self)
  end

  # lECTURE TO USER (JOINING) RELATIONSHIPS
  def joined?(selected_lecture)
    lecturerelationships.find_by_joinedlecture_id(selected_lecture.id)
  end

  def join!(selected_lecture)
    lecturerelationships.create!(:joinedlecture_id => selected_lecture.id)
  end

  def exit!(selected_lecture)
   lecturerelationships.find_by_joinedlecture_id(selected_lecture.id).destroy
  end


end

Thanks for any and all help - i'll be on here for a while so as mentioned i'd GREATLY appreciate someone who may have the time to work through my issues with me... 感谢您提供的所有帮助-我会在这里待一会儿,如上所述,我将非常感谢有人可能有时间与我一起解决我的问题...

I would start with the following models, using Enrollment for the membership table. 我将从以下模型开始,将Enrollment用于成员资格表。
Class naming is critical for this. 为此,类命名至关重要。

class User < ActiveRecord::Base
  has_many :enrollments
  has_many :users, :through => :enrollments
end

class Lecture < ActiveRecord::Base
  has_many enrollments
  has_many users, :through => :enrollments
end

class Enrollment < ActiveRecord::Base
  belongs_to :user
  belongs_to :lecture
end

The main trick to rails is using the right names and following the conventions and letting the framework do most of the work for you. Rails的主要技巧是使用正确的名称并遵循约定,并让框架为您完成大部分工作。 Step off the path and the errors can be endless and the code gets messy quickly :) 走出这条路,错误可能无穷无尽,代码很快就会变得混乱:)

It looks like your _join.html.erb uses build to form a new lecturerelationships association and then the join! 看来您的_join.html.erb使用build了一个新的lecturerelationships关系关联,然后join! call uses create to make another one on the same object. 调用使用create在同一对象上create另一个对象。 My guess is that the second call interrupts a transaction started by the first one and that's why you are getting the database is locked: commit transaction error. 我的猜测是第二个调用中断了第一个调用启动的事务,这就是为什么database is locked: commit transaction错误。

I think it is considered good practice to keep this sort of code out of your views. 我认为将这种代码置于您的意见范围之外是一种很好的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM