我试图在Ruby on Rails中创建一个应用程序,我可以:
创建会议(工作)
查看会议列表(工作)
关注并取消关注会议(不工作)
查看以下会议(不工作)
我在12月份开始使用Ruby on Rails并使用Micheal Hartl的教程开始。在第14章(https://www.railstutorial.org/book/following_users)中,迈克尔通过关系介绍了跟随和取消关注的用户。
我尝试应用他的技术,但将其调整到一个模型和一个控制器之间的关系,到两个模型和两个控制器的位置。
一个控制器& model是User_controller和User Model,另一个是控制器& model是Conference_controller和Conference Model。
我首先将活跃的关系添加到用户模型中,因为它是参加会议的一方
user.rb
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
我在会议模式中做了相反的事情,因为我关注的是被关注的一方
Conference.rb
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :followers, through: :passive_relationships, source: :follower
为了清除结构,我已将以下代码行添加到关系模型
Relationship.rb
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "Conference"
validates :follower_id, presence: true
validates :followed_id, presence: true
当试图查看用户是否实际关注会议时,用户模型中出现错误:
ActiveRecord::RecordNotUnique in RelationshipsController#create
SQLite3::ConstraintException: UNIQUE constraint failed: relationships.follower_id, relationships.followed_id: INSERT INTO "relationships" ("follower_id", "followed_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)
问题的根源在于:
app/models/user.rb:116:in `follow'
app/controllers/relationships_controller.rb:6:in `create'
我理解当无法插入记录时会出现问题,因为它会违反唯一性约束,但我不知道违反了什么唯一性约束。
现在第一个问题出现在 user.rb 中,当在用户和会议之间创建active_relationship时。
# Returns true if the current user is following the other user.
def following?(other_conference)
following.include?(other_user)
end
# Follows a conference.
def follow(other_conference)
active_relationships.create(followed_id: other_conference.id)
end
# Unfollows a conference.
def unfollow(other_conference)
active_relationships.find_by(followed_id: other_conference.id).destroy
end
第二个问题出在Relationships_controller中,current_user应该跟随会议。
def create
@conference = Conference.find(params[:followed_id])
current_user.follow(@conference)
respond_to do |format|
format.html { redirect_to @conference }
format.js
end
end
现在我不确定问题的原因是什么以及如何解决。我希望我能清楚地解决问题以及我想要实现的目标。如果不是,我很乐意提供有关我的问题的更多信息。
答案 0 :(得分:1)
您正在关注一个处理更复杂案例的示例(您将两次加入同一个表格)并且您的解决方案比它需要的更复杂:
class User
has_many :subscriptions
has_many :conferances, though: :subscriptions
def subscribed_to?(conference)
conferances.include?(conference)
end
def find_subscription(conference)
subscriptions.find_by(conference: conference)
end
end
class Conferance
has_many :subscriptions
has_many :users, though: :subscriptions
end
# Its better to name join models after an actual thing
class Subscription
belongs_to :user
belongs_to :conference
end
resources :conferences, shallow: true do
resource :subscriptions, only: [:create, :destroy]
end
class SubscriptionsController
before_action :set_conferance, only: :create
def create
if current_user.subsciptions.create(conferance: @conferance)
flash[:success] = "You are now subscribed to { @conferance.name }"
else
flash[:error] = "Could not create subscription."
end
redirect_to @conferance
end
def destroy
@subscription = current_user.subsciptions.find(params[:id])
if @subscription.destroy
flash[:success] = "You are no longer subscribed to { @conferance.name }"
else
flash[:error] = "Oh noes"
end
redirect_to @subscription.conferance
end
def set_conferance
@conferance = Conferance.find(params[:conferance_id])
end
end
<% if current_user.subscribed_to?(@conferance) %>
<%= button_to "Subscribe", conferance_subsciptions_path(@conferance), method: :post %>
<% else %>
<%= button_to "Unsubscribe", subscription_path(current_user.find_subscription(@conferance)), method: :delete %>
<% end %>