Now I am trying to set up switching button to follow someone.
<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-->
But I got an error message.
undefined method `friend_id' for #<ActiveRecord::Relation:0x007fc4b54935f0>
and looked into #isFr and it has
>> #isFr
=> [#<Friend id: 196, member_id: 2, friend_id: 3, created_at: "2013-12-23 01:28:18", updated_at: "2013-12-23 01:28:18">]
So, I can't extract friend_id value from #isFr.
How can I solve this?
☆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
#isFr =Friend.where(:member_id => session[:user_id], :friend_id => #members.map(&:id)).limit(1)
respond_to do |format|
format.html # index.html.erb
format.json
end
end
☆index.html.erb(members#index)
<table class="table">
<tr>
<th>写真</th>
<th>名前</th>
<th>分野</th>
<th>場所</th>
<th>経験</th>
<th></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>
<%= member.name %>
<% 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>
The problem is at this line
#isFr =Friend.where(:member_id => session[:user_id], :friend_id => #members.map(&:id)).limit(1)
That will respond a ActiveRecord::Relation but you need a Friend object. Try this
#isFr =Friend.where(:member_id => session[:user_id], :friend_id => #members.map(&:id)).first
Related
I am learning to use CRUD, and setup a page to add a record, however it only generated blank record? Can you take a look my code?
thanks!
here is the Page controller:
class PagesController < ApplicationController
def index
#test = Page.all
end
def new
#test = Page.new
end
def create
#test = Page.new(params.permit(:subject_id,:name,:position,:visible,:permalink))
if #test.save
flash[:notice] = "Page created successfully!"
redirect_to(:action => 'index')
else
render('new')
end
end
end
here is the new.html.erb
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="pages new">
<h2>Create Subject</h2>
<%= form_for(:Page, :url => {:action => 'create'}) do |f| %>
<table summary="Page form fields">
<tr>
<th>Subject_ID</th>
<td><%= f.text_field(:subject_id) %></td>
</tr>
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th>Position</th>
<td><%= f.text_field(:position) %></td>
</tr>
<tr>
<th>Visible</th>
<td><%= f.text_field(:visible) %></td>
</tr>
<tr>
<th>Permalink</th>
<td><%= f.text_field(:permalink) %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Create Subject") %>
</div>
<% end %>
</div>
Here is index.html.erb
<div class="pages index">
<h2>Pages</h2>
# <%= link_to("Add New Page", {:action => 'new'}, :class => 'action new') %>
<table class="listing" summary="Page list">
<tr class="header">
<th>Position</th>
<th>Page Name</th>
<th>Visible</th>
<th>Pages</th>
<th>Actions</th>
</tr>
<% #test.each do |f| %>
<tr>
<td><%= f.position %></td>
<td><%= f.name %></td>
<td class="center"><%= f.visible %></td>
<td class="center"><%= f.permalink %></td>
<td class="actions">
<%= link_to("Show", {:action => 'show', :id => f.id}, :class => 'action show') %>
<%= link_to("Edit", {:action => 'edit', :id => f.id}, :class => 'action edit') %>
<%= link_to("Delete", {:action => 'delete', :id => f.id}, :class => 'action delete') %>
</td>
</tr>
<% end %>
</table>
</div>
Thanks so much!
Strong parameters
Rails sends form parameters in nested hashes.
{ page: { subject_id: 1, name: 'Hello World.' } }
So to whitelist the parameters you would do.
class PagesController < ApplicationController
def index
#test = Page.all
end
def new
#test = Page.new
end
def create
#test = Page.new(page_params)
if #test.save
flash[:notice] = "Page created successfully!"
redirect_to(:action => 'index')
else
render('new')
end
end
private
def page_parameters
params.require(:page)
.permit(:subject_id,:name,:position,:visible,:permalink)
end
end
which is like doing:
params[:page].slice(:subject_id,:name,:position,:visible,:permalink)
form_for and models
Also your form should read:
<%= form_for(:page, :url => {:action => 'create'}) do |f| %>
Or:
<%= form_for(#page, :url => {:action => 'create'}) do |f| %>
:Page will give you the wrong key in your parameters and prevent rails from binding the form to your #page object. (The values posted will disappear from the form when it's invalid).
Now I am trying to add "follow button" on my users' index page.
My goal is like... when users push the button once, the message beside the button turns "following". And he or she push it again, the message turns "not following". Default message is "not following".
And then I wrote the codes below but got an error message.Could you tell me how to solve this problem?
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>
<%= member.name %>
<% 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
Below query must be returning blank AR
#members = Member.where("id >=1")
.order("created_at desc")
.paginate(:page => params[:page], :per_page => 10).scoped
And #isFr is eventually resulting in nil
#members.each do |m|
#isFr = Friend.where(:member_id => session[:user_id], :friend_id =>
m.id ).first
end
Just a word of refactor you can do
Friend.where(:member_id => session[:user_id], :friend_id => #members.map(&:id)) .limit(1)
But would be better if you think on the associations between your models. That way it will optimize with join queries
Thanks to those who gave me hints, I made it with the code below.
☆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
The problem here is that the instance var #isFr in your index action returns nil. That means the code Friend.where(:member_id => session[:user_id], :friend_id => m.id ).first is returning nil.
You could do <% if #isFr.try(:friend_id) == member.id %> in your members#index view so that that you won't get the NoMethodError.
There's something wrong with the below code I found in your index action:
#members.each do |m|
#isFr = Friend.where(:member_id => session[:user_id], :friend_id => m.id ).first
end
The problem with the code above is that #isFr will only retain value of the last element in #members array. It's better to add a method in the Member model for that behavior like this:
#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) }
Then use it in your view like:
<% unless session[:user_id] == member.id %> # below this line of code
<% if Friend.get_member_id(member, session[:user_id]) == member.id %>
Hope this helps!
Now, I tried to set up the route with group_path(#group) but got an error message like,
ActiveRecord::RecordNotFound at /groups/%23%3CActiveRecord::Relation:0x007fd6cf362538%3E
Couldn't find Group with id=#<ActiveRecord::Relation:0x00fds6cf362538>
Here is my code. I would like to set up a link to groups/show/:id. Why did this error occur? Could you give me how to solve this?
☆index.html.erb
<% if #items.present? %>
<% #items.each do |i| %>
<% i_attr = i.get_element('ItemAttributes') %>
<tr>
<td> <%= link_to image_tag(i.get('SmallImage/URL'), {:style => 'border: none;'}), i_attr.get('DetailPageURL') %></td>
<td> <%= link_to i_attr.get('Title'), i_attr.get('DetailPageURL') %></td>
<td> <%= i_attr.get('Author') %></td>
<td> <%= i_attr.get('PublicationDate')%></td>
<td> <%= i_attr.get('Publisher') %></td>
<td> <%= i_attr.get('NumberOfPages')%></td>
<td>
<% if #existing_groups_isbns.include? i_attr.get('ISBN') %>
<% #existing_groups_isbns.each do |isbn| %>
<% if isbn == i_attr.get('ISBN') %>
<% #group = Group.where(:isbn =>isbn) %>
<%= link_to '既存ページへ' , group_path(#group) %>
<% end %>
<% end %>
<% else %><!-- if includes?==-->
<%= link_to '新規作成', {:controller => 'groups', :action => 'new', :name => i.get('ItemAttributes/Title'),:author => i.get('ItemAttributes/Author'), :publish => i.get('ItemAttributes/Publisher'), :published => i.get('ItemAttributes/PublicationDate'), :isbn => i.get('ItemAttributes/ISBN'), :page => i.get('ItemAttributes/NumberOfPages'), :imageurl=>i.get('MediumImage/URL')} ,class: "btn btn-midium btn-primary"%>
<% end %><!--if includes?-->
</td>
</tr>
<% end %><!-- #items.each do-->
<% else %><!--if #items.present?-->
見つかりませんでした。
<% end %><!-- if #items.present?-->
☆index_controller
def index
#keyword = params[:keyword]
if #keyword.present?
Amazon::Ecs.debug = true
res = Amazon::Ecs.item_search(params[:keyword],
:search_index => 'All', :response_group => 'Medium')
#items = res.items
search_isbns = #items.map{ |isbns| isbns.get('ItemAttributes/ISBN')}
search_asins = #items.map{ |asins| asins.get('ItemAttributes/ASIN')}
#existing_groups_isbns = Group.select(:isbn).where(:isbn => search_isbns).map(&:isbn)
#existing_groups_ids = Group.where(:isbn => search_isbns).map{|g| g.id}
end
Replace
<% #group = Group.where(:isbn =>isbn) %>
with
<% #group = Group.where(:isbn =>isbn).first %>
Because you need an object where you had an ActiveRecord relation
I implemented a chat system to my app.
It refreshes the list of comments partially when after new comment was submit.
So new added comment pops up without reloading whole page.
It's working fine but the problem is, it won't make input field empty(initialize) after submit :(
How can I make it empty if it succeeded at submitting?
5 seconds Auto-refreshing will be another issue that's preventing.
So I have to care about it, too.
and If possible I want to pop up flash alert 'you cant spam' when the user tried to submit comment within 10 seconds.
Let's assume as if I'm trying to submit comment from Users#show page
views/users/show.html.erb
<%= javascript_tag do %>
jQuery(document).ready(function () {
refreshPartial();
setInterval(refreshPartial, 5000)
});
function refreshPartial() {
$.ajax({
url: "<%= show_user_path(#user) %>/refresh_part",
type: "GET",
dataType: "script",
});
}
<% end %>
......
<span id="chat">
<%= render 'users/comment' %>
</span>
<%= render 'users/comment_input' %>
views/users/_comment.html.erb
<table>
<tr>
<th>ID</th>
<th>PIC</th>
<th>Body</th>
<th>Subject</th>
<th>Posted by</th>
<th>Delete</th>
</tr>
<% #comments.each do |comment| %>
<tr id="<%= dom_id(comment) %>">
<td><%= comment.id %></td>
<td>
<% if comment.comment_icon? %>
<ul class="thumbnails">
<%= image_tag(comment.comment_icon.url(:thumb),:height => 100, :width => 100, :style => 'border:3px double #545565;' ) %>
</ul>
<% end %>
</td>
<td><%= comment.body %></td>
<td><%= comment.subject %></td>
<td><%= comment.user.user_profile.nickname if comment.user.user_profile %></td>
<td>
<%= button_to 'destroy', polymorphic_path([#user, comment]), :data => {:confirm => 'Are you sure?'}, :method => :delete, :disable_with => 'deleting...', :remote => true, :class => 'btn btn-danger' if current_user && current_user.id == comment.user_id %>
</td>
</tr>
<% end %>
</table>
<%= paginate #comments, :window => 4, :outer_window => 5, :left => 2, :right => 2 %>
views/users/_comment_input.html.erb <= This is input form!!!!!
<%=form_for(([#user, #comment]), :remote => true) do |f| %>
<div class="field">
<%= f.label :body %><br />
<%= f.text_field :body %>
</div>
<div class="field">
<%= f.file_field :comment_icon %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
comments_controller.rb
def create
commentable = #community_topic||#community||#user
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = Comment.build_from(commentable, current_user.try(:id), params[:comment][:body])
#comment.comment_icon = params[:comment][:comment_icon]
if #user
#following_users = #user.all_following(order: 'updated_at DESC')
#followed_users = #user.followers
#communities_user = #user.get_up_voted(Community).order("updated_at ASC").page(params[:page]).per(5)
elsif #community
end
last_comment = Comment.where(:user_id => current_user.id).order("updated_at").last
if last_comment && (Time.now - last_comment.updated_at) <= 10.second
flash[:notice] = "You cannot spam!"
render :template => template_for(commentable)
elsif #comment.save
#if #community_topic.empty?
#comments = commentable.comment_threads.order("updated_at DESC").page(params[:page]).per(5)
#comment = commentable.comment_threads.build
respond_to do |format|
format.html { redirect_to [#community, commentable].uniq, :notice => "comment added!" }
format.js do
if #community.present?
render 'communities/refresh_part'
elsif #community_topic.present?
render 'community_topics/refresh_part'
elsif #user.present?
render 'users/refresh_part'
end
end
end
else
render :template => template_for(commentable)
end
end
views/users/refresh_part.js.erb
$('#chat').html("<%= j(render(:partial => 'users/comment')) %>")
Well I assume this is the "body" input you want to empty so basically, just add an id to it like this :
<%= f.text_field :body, :id => "body_input" %>
And in your views/users/refresh_part.js.erb, you can add something like :
$('#body_input').val('');
This should work only if it succeded at submitting because from what I saw, your template is rendered only if the comment is saved.
I'm using Rails3. Now trying to implement follow button in index.html.erb just like twitter.
It shows member list and their follow buttons.
It looks okay but if I press any of those follow button, appearance doesn't change.
It should changes follow to un-follow right away.
I have no idea why it does. But if I reload the page, it shows correct status.
follows_controller.rb
class FollowsController < ApplicationController
def create
#user = User.find(params[:user_id])
current_user.follow(#user)
respond_to do |format|
format.js {render :action=>"create.js"}
end
end
def destroy
#user = User.find(params[:user_id])
current_user.stop_following(#user)
respond_to do |format|
format.js {render :action=>"destroy.js"}
end
end
end
views/users/_follow_user.html.erb
<% unless user == current_user %>
<% if current_user.following?(user) %>
<%= button_to("Un-Follow", user_follow_path(user.to_param, current_user.get_follow(user).id),
:method => :delete,
:remote => true,
:class => 'btn') %>
<% else %>
<%= button_to("Follow", user_follows_path(user.to_param),
:remote => true,
:class => 'btn btn-primary') %>
<% end %>
<% end %>
views/users/create.js.erb
$('.follow_user[data-user-id="<%=#user.id%>"]').html('<%= escape_javascript(render :partial => "follow_user", :locals => {:user => #user}) %>');
#jQuery
views/users/destroy.js.erb
$('.follow_user[data-user-id="<%=#user.id%>"]').html('<%= escape_javascript(render :partial => "follow_user", :locals => {:user => #user}) %>');
#jQuery
views/users/index.html.erb
<%- model_class = User.new.class -%>
<div class="page-header">
<h1><%=t '.title', :default => model_class.model_name.human.pluralize %></h1>
</div>
<% #from %>
<h3>tag cloud</h3>
<% tag_cloud(#tags, %w(css1 css2 css3 css4)) do |tag, css_class| %>
<%= link_to tag.name, {:action=>'index', :tag=>tag.name}, :class => css_class%>
<% end %>
<%= paginate #users %>
<table class="table table-condensed">
<thead></thead>
<tbody>
<% #users.each do |user| %>
<div class="memberListBox">
<div class="memberList">
<p class="name"><span><%= user.user_profile.nickname %></span>(<%= user.user_profile.age %>)</p>
<p class="size"><%= user.username %></p>
<p class="img">
<% if user.user_profile.user_avatar? %>
<%= image_tag(user.user_profile.user_avatar.url(:thumb),:height => 100, :width => 100, :class => 'img-polaroid' ) %>
<% else %>
<%= image_tag('nophoto.gif',:height => 100, :width => 100, :class => 'img-polaroid' ) %>
<% end %>
</p>
<div class="introduction">
<%= user.user_profile.introduction %>
</div>
<% if user_signed_in? && current_user!=user %>
<div id="follow_user">
<%= render :partial => "follow_user", :locals => {:user => user} %>
</div>
<% end %>
<%= link_to sanitize('<i class="icon-pencil icon-white"></i> ') + 'Message', new_messages_path(user.username), :class => 'btn btn-primary' %>
<%= link_to sanitize('<i class="icon-user icon-white"></i> ') + 'Profile', show_user_path(:username => user.username, :breadcrumb => #from), :class => 'btn btn-info' %>
</div>
</div>
<% end %>
</tbody>
</table>
response content
$('#follow_user').html(' <form action=\"/users/1/follows\" class=\"button_to\" data-remote=\"true\" method=\"post\"><div><input class=\"btn btn-primary\" type=\"submit\" value=\"Follow\" /><input name=\"authenticity_token\" type=\"hidden\" value=\"G/taOUeWy2gumhWUi10cPvECAmYLQdhQ2/eGGMJwvPE=\" /><\/div><\/form>\n');
Add the user id to the attribute data-user-id and add the class follow_user
<div class="follow_user" data-user-id="<%= user.id %>">
<%= render :partial => "follow_user", :locals => {:user => user} %>
</div>