我有兴趣制作类似于SO的功能,其中提出问题的用户可以从响应列表中选择答案,但我仍然坚持如何从控制器角度处理点击事件。
目前,我的模型Question
为has_many
answers
。此外,我制作了Selection
模型,用于表示答案选择,其中每个Question
只能has_one
选择答案。
我在问题的show
动作中回答每个问题的答案和问题。在我的_answer
部分中,我想提出以下逻辑:“如果提出问题的用户已登录,他可以看到链接'取消选择'答案如果相关selection
已经存储了answer_id
的答案(换句话说,标记此答案之前已被选中),否则他可以“选择”将答案存储在{answer_id
中的答案selection
1}}。(我应该提一下,我在Rails tutorial处修改了下面的大部分代码,其中我(遗憾的是)我不太清楚如何使用POST
来匹配或分配属性到实例变量)
<% if current_user?(answer.question.user) %>
<% if current_user.selections.where(:answer_id => answer.id) == answer.id %>
<%= link_to "unselect", selections_path(:selection => {:answer_id => nil}), :method => :post %>
<% else %>
<%= link_to "select", selections_path(:selection => {:answer_id => answer.id}), :method => :post %>
<% end %>
<% end %>
我的包版广告位于控制器中,如果用户通过“{{1}”方法将the create
变量分配给新的@selection
,我将无法通过“选择”链接。任何帮助,或任何关于如何写点击事件的指南将非常感激。谢谢!
答案 0 :(得分:1)
有很多不同的方法可以做到这一点,但我倾向于认为你有设计问题,所以这就是我将如何做到这一点。
我假设您所说的关联看起来像这样:
__________ ________
| Question |1 *| Answer |
| |<-------------------------------| |
| |1 * ___________ * 1| |
| |<------| Selection |----------->|________|
| | | |
| | | |* 1 ________
| | |___________|----------->| User |
| |* 1| |
|__________|------------------------------->|________|
此直观表示清楚地显示了问题:您的Selection
模型是多余的,因为它代表了问题belongs_to
和User
(我们已经知道)的事实;如果每对Question / User
可以有多个选择,那就不会多余,但实际上我们希望这对于每对夫妇来说都是唯一的......
belongs_to
和Question
之间的Answer
关系可以实现与Selection
模型相同的功能,事实上它可以做得更好因为您不需要所有逻辑来找到正确的选择,并确保它是唯一的/用户是问题的正确拥有者等。
所以这就是我要做的事情:
在Question
模型中
has_many :answers, inverse_of: :question
belongs_to :accepted_answer, class_name: :answer, foreign_key: :accepted_answer_id
在Answer
模型中
belongs_to :question, inverse_of: :answers
def accepted?
return false if new_record?
question.try( :accepted_answer_id ) == id
# an alternative is to use question.try( :accepted_answer ) == self
end
在您的路线中
resources :questions do
member do
# we use put because these are update actions
put :accept_answer
put :clear_accepted_answer
end
end
在QuestionsController
respond_to :js, only: [:accept_answer, :clear_accepted_answer]
def accept_answer
@question = Question.find( params[:id] )
# ...cue some logic to ensure current_user
# has required rights to update the question
if @question.update_attributes( accepted_answer_id: params[:answer_id] )
# ...render the js that updates your view (for example,
# find and replace calling link with an "unselect" one )
else
# .. an error has occurred, render an "unprocessable entity" status
end
end
def clear_accepted_answer
@question = Question.find( params[:id] )
# ...cue some logic to ensure current_user
# has required rights to update the question
if @question.update_attributes( accepted_answer_id: nil )
# ...render the js that updates your view (for example,
# find and replace calling link with a "select" one )
else
# .. an error has occurred, render an "unprocessable entity" status
end
end
<% if current_user?(answer.question.user) %>
<% if answer.accepted? %>
<%= link_to "unselect",
clear_accepted_answer_question_path( answer.question ),
method: :put,
remote: true %>
<% else %>
<%= link_to "select",
accept_answer_question_path(
answer.question,
answer_id: answer.id
),
method: :put,
remote: true %>
<% end %>
<% end %>