现在我正在尝试在用户的索引页面上添加“关注按钮”。
我的目标是......当用户按下按钮一次时,按钮旁边的消息变为“跟随”。并且他或她再次推动它,消息变成“不跟随”。默认消息是“不跟随”。
然后我写了下面的代码,但收到了错误信息。你能告诉我如何解决这个问题吗?
NoMethodError at /members undefined method `friend_id' for nil:NilClass
☆index.html.erb(members_controller)
<table class="table">
<tr>
<th>写真</th>
<th>名前</th>
<th>分野</th>
<th>場所</th>
<th>経験</th>
<th>Follow</th>
<%# if Member.find(session[:user_id]).admin %>
<%# end %>
</tr>
<% @members.each do |member| %>
<tr>
<td>
<% if member.provider %>
<%=image_tag member.image ,:size=>'30x30'%>
<% elsif member.avatar_file_name %>
<%= image_tag member.avatar.url(:thumb), :width =>'30px', :height =>'30px' %>
<% else %>
<%= image_tag "love.png", :size=>'30x30' %>
<% end %>
</td>
<td>
<a href="/members/<%= member.id %>"><%= member.name %></a>
<% if member.provider == "facebook" %>
<a target="_blank" href="http://www.facebook.com/<%=member.uid %>"> <%=image_tag "fb.png" ,:size=>'20x20'%> </a>
<% elsif member.provider == "twitter" %>
<a target="_blank" href="http://www.twitter.com/<%=member.name %>"> <%=image_tag "twitter.png" ,:size=>'20x20'%> </a>
<% end %>
</td>
<td><%= member.field %></td>
<td>
<% if member.url.present? %>
<%=link_to member.place ,member.url ,:target=>["_blank"] %>
<% else %>
<%= member.place %>
<% end %>
</td>
<td><%= member.experience %></td>
<td>
<div class="onoff">
<% unless session[:user_id] == member.id %>
<% if @isFr.friend_id == member.id %>
<%= link_to'off', {:controller => 'members', :action => 'index', :id =>
member.id}, class: "btn btn-midium btn-primary"%><br/>
※following
<% else %>
<%= link_to'on', {:controller => 'members', :action => 'index', :id =>
member.id}, class: "btn btn-midium btn-primary"%><br/>
※not following
<% end %>
<% end %>
</div>
<%#= member.friends.count %>
</td>
<% if Member.find(session[:user_id]).admin %>
<td><%= link_to 'Destroy', member, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
</table>
☆members_controller
def index
if !checklogin? then return end
@members = Member.where("id >=1").order("created_at desc").paginate(:page => params[:page], :per_page => 10).scoped
if params[:name].present?
@members = @members.where("name like ?" , "%" + params[:name] + "%")
end
if Friend.where(:member_id => session[:user_id], :friend_id => params[:id]).exists? then
Friend.where(:member_id => session[:user_id], :friend_id => params[:id]).each do |f|
f.destroy
end
else
Friend.new({:member_id => session[:user_id], :friend_id =>params[:id].to_i}).save
end
@members.each do |m|
@isFr = Friend.where(:member_id => session[:user_id], :friend_id =>
m.id ).first
end
respond_to do |format|
format.html # index.html.erb
format.json
end
end
☆sessions_controller #session [:user_id]
auth = request.env["omniauth.auth"]
member = Member.find_by_provider_and_uid(auth["provider"], auth["uid"])
session[:user_id] = member.id
答案 0 :(得分:0)
这里的问题是索引操作中的实例var @isFr返回nil。这意味着代码Friend.where(:member_id => session[:user_id], :friend_id => m.id ).first
返回nil。
您可以在您的成员#index视图中执行<% if @isFr.try(:friend_id) == member.id %>
,这样您就不会得到NoMethodError。
我在索引操作中找到的以下代码有问题:
@members.each do |m|
@isFr = Friend.where(:member_id => session[:user_id], :friend_id => m.id ).first
end
上面代码的问题是@isFr只保留@members数组中最后一个元素的值。最好在Member模型中为这种行为添加一个方法,如下所示:
#in app/models/friend.rb
scope :get_member_id, ->(member, user_id) { where(:member_id => user_id, :friend_id => member.id ).first.try(:friend_id) }
然后在您的视图中使用它,如:
<% unless session[:user_id] == member.id %> # below this line of code
<% if Friend.get_member_id(member, session[:user_id]) == member.id %>
希望这有帮助!
答案 1 :(得分:0)
以下查询必须返回空白AR
@members = Member.where("id >=1")
.order("created_at desc")
.paginate(:page => params[:page], :per_page => 10).scoped
@isFr
最终会产生nil
@members.each do |m|
@isFr = Friend.where(:member_id => session[:user_id], :friend_id =>
m.id ).first
end
你可以做一个重构词
Friend.where(:member_id => session[:user_id], :friend_id => @members.map(&:id)) .limit(1)
但如果你考虑模型之间的associations会更好。这样它将使用连接查询进行优化
答案 2 :(得分:0)
感谢那些给我提示的人,我使用下面的代码制作了它。
☆index.html.erb(members_controller)
<td>
<div class="onoff">
<% unless session[:user_id] == member.id %>
<% if @Frids.include? member.id%>
<%= link_to'Off', {:controller => 'members', :action => 'index', :id =>
member.id}, class: "btn btn-midium btn-warning"%><br/>
※既follow
<% else %>
<%= link_to'On', {:controller => 'members', :action => 'index', :id =>
member.id}, class: "btn btn-midium btn-primary"%><br/>
※未follow
<% end %>
<% end %>
</div>
<%#= member.friends.count %>
</td>
☆members_controller
def index
if !checklogin? then return end
@members = Member.where("id >=1").order("created_at desc").paginate(:page => params[:page], :per_page => 10).scoped
if Friend.where(:member_id => session[:user_id], :friend_id => params[:id]).exists? then
Friend.where(:member_id => session[:user_id], :friend_id => params[:id]).each do |f|
f.destroy
end
else
Friend.new({:member_id => session[:user_id], :friend_id =>params[:id].to_i}).save
end
@Frids =Friend.where(:member_id => session[:user_id]).map{|x| x.friend_id}
respond_to do |format|
format.html # index.html.erb
format.json
end
end