i implemented a friendship model using rails 3.. now i want to enable the users to add new friends...from the looks of it, i guess i need 2 for loops...one for looping all the users and another one for checking if that user is already a friend.... but if i use 2 for loops, i don't get the result that i am expecting and the email of the users who are alraedy the friends of current user prints and the address gets printed multiple times (because of the 2nd for loop as i am printing it inside the loop) .. is there any other way to get around this issue????
code:
this is my view file:
<center>Bragger's list<center><br/>
<p>
<% for user in User.all %>
<% if current_user.email!= user.email %>
<% for friend in current_user.friends %>
<% if friend.email!=user.email %>
<p>
<%= user.email %> <%= link_to 'Add as Friend' , friendships_path(:friend_id => user), :method => :post %>
</p>
<br/>
<%end%>
<%end%>
<%end%>
<%end%>
The best approach to this is to filter the list of users in your controller that is not yet a friend of the current_user. You can do that by
#potential_friends = User.where('id != ? AND id NOT IN (?)', current_user.id, current_user.friend_ids)
Then just loop over this variable in the view
<center>Bragger's list<center><br/>
<p>
<% #potential_friends.each do |user| %>
<p>
<%= user.email %> <%= link_to 'Add as Friend' , friendships_path(:friend_id => user), :method => :post %>
</p>
<br/>
<% end %>
</p>
How about doing something else,
User.where('user_id not in (?)', current_user.friends.map(&:id).push(current_user.id))
This would get all the users from the database that are not your current_user's friends and then you have only to loop once.
Related
let me start that I am new to rails, so far I have been able to solve all the issue I have had until now. I can confirm that my database is set and the relationships are working. Here is my issue, the app is similar to a project management tool. I have users that can create ski swaps and then search for vendors, then I render the results with javascript( ajax) so I dont have to reload the page. I added a badge so that I can use this to add the user as a vendor. As of right now I can get the user params no problem but the skiswap params I can't seem to get them to comeover I have tried. if I hardcode it it will work so I'm close but can not figure this out
Inside my
skiswap#index I have this for the search Above this I use #skiswap
<%= form_tag search_vendors_path, remote: true, method: :get do %>
<div class='form-group row'>
<div class ="input-group col-sm-3">
<%= text_field_tag :search, params[:search], placeholder: "Shop name, email, or contact...", autofocus: true, class: "form-control form-control-sm"%>
<div class="input-group-prepend">
<%= button_tag type: :submit, class: "btn btn-info btn-sm", id: "small-serach" do %>
<i class="fas fa-search" id = "search-icon"></i>
<% end %>
</div>
</div>
</div>
<% end %>
My search is working and this is what I have in the VendorController
def search
#users = User.where(["concat_ws(' ' , first_name, last_name, email, company ) ILIKE ?", "%#{params[:search]}%"])
respond_to do |format|
format.js{ render partial: 'skiswaps/result'}
end
end
My results are here and this is the badge I use to add new vendor, currently I have it hard coded because I cant figure it out. I am using j render for my results... I have tried skiswap_vendors_path(vendor: user, skiswap_id: #skiswap.id) also skiswap_vendors_path(vendor: user, skiswap: #skiswap) #skiswap is showing up as nil. Wasnt sure if it because my results are part of a partail, they dont seem to have the params that should be in show page.
<% #users.each do |user| %>
<tr>
<td><%= link_to "Add", skiswap_vendors_path(vendor: user, skiswap_id: 4),
class: "badge badge-success", method: :post %></td>
<td> <strong>Shop: </strong><%= user.company %> </td>
<td> <strong>Contact: </strong><%= user.first_name %> <%= user.last_name %>, <%= user.email%></td>
</tr>
<% end %>
Then in my VendorController I have this to create, which only works if I hardcode it
def create
vendor = User.find(params[:vendor])
skiswap = Skiswap.find(params[:skiswap_id])
skiswap.vendors.build(user_id: vendor.id)
if skiswap.save
flash[:notice] = "You add #{vendor.company} as a vendor"
else
flash[:notice] = "Sorry something went wrong, try again later"
end
end
This is what I have for routes
get 'search_vendors', to: 'vendors#search'
resources :skiswaps do
resources :vendors
end
I had to add in a hidden field tag to get the #skiswap.id through
<%= form_tag search_vendors_path, remote: true, method: :get do %>
....
<%= hidden_field_tag :skiswap_id, #skiswap.id %>
<% end %>
Using two different models, RecordLabel and Artist, I want to link to their pages if the record is found using their usernames. I have no problems finding if the record exists, but I can't figure out how to find the ID of that record. What I have:
<% if RecordLabel.exists?(:username => "#{#artist.artist_profile.record_label_name}") %>
<%= link_to #artist.artist_profile.record_label_name, record_label_path(RecordLabel.find(### NEED RECORD LABEL ID ###) %>
<% else %>
<%= #artist.artist_profile.record_label_name %>
<% end %>
You can get the record very easily this way (if it exists):
RecordLabel.where(:username => "#{#artist.artist_profile.record_label_name}").first
So, your code becomes:
<% if RecordLabel.exists?(:username => "#{#artist.artist_profile.record_label_name}") %>
<%= link_to #artist.artist_profile.record_label_name,
record_label_path(RecordLabel.where(:username => "#{#artist.artist_profile.record_label_name}").first) %>
<% else %>
<%= #artist.artist_profile.record_label_name %>
<% end %>
This should work and solve your problem.
I came from a JS background so Rails is weird to me. I currently have a show.html.erb for the contest model:
<h1>Contest name: <%= #contest.name %></h1>
<h2>Contest criteria: <%= #contest.criteria %></h2>
<h3>Photos: </h3>
<%= link_to "Enter Contest", "#" %>
<% #contest.photos.each do |photo| %>
<%= image_tag("#{photo}") %>
<% end %>
With the link_to I'm trying to render all photos that belongs to the current_user and pick one of them to assign it to the current contest. The params passing seems all so mysterious to me. Can you guys point me in the right direction of how I should tackle this problem? Thanks
What I understand you need to select an image from list of images and pass the id. So, try this
<%= label_tag "Enter Contest" %>
<% #contest.photos.each do |photo| %>
<%= link_to (image_tag("#{some photo path}")), some_controller_method_path(:photo_id => photo.id) %>
<% end %>
And in controller you can use params[:photo_id]
I want to update a model - only lines where the checkox is clicked and insert a remark
View:
<%= form_tag update_fb_instruction_users_path, :method => :put do %>
<% #user_wishes.each do |u| %>
<%= u.user.name %>
<%= fields_for "instruction[]", u do |f| %>
<%= f.text_field :remark_tl %>
<% end %>
<%= check_box_tag "instruction_user_ids[]", u.id %>
<% end %>
Controller:
def update_fb
params[:instruction_user_ids].each do
#check = InstructionUser.update(params[:instruction].keys, params[:instruction].values).reject { |p| p.errors.empty? }
end
The issue there is that they all have the same name. So whatever value the last one is, that's what it will be in the request params.
It's a bit old, but you might want to check out the railscast here: http://railscasts.com/episodes/73-complex-forms-part-1. The basic idea is to use fields_for on top of each user object. I haven't done it myself before, otherwise i'd write a full solution :).
I imagine this has a rather simple answer
<% for user in #users %>
<li>
<%= link_to user.username, user %>
</li>
<% end %>
Taking my simple example above, how would I apply a class to my <li> to the first three instances returned?
Secondly, how could I just have the the second two items have a different class from the first one? as in 1..2
Either you could count manually (which is kinda ugly):
<% i = 0 %>
<% for user in #users %>
<li class=<%= (i < 3 ? "foo" : "bar") %>>
<%= link_to user.username, user %>
</li>
<% i = i.next %>
<% end %>
or use each_with_index
<% #users.each_with_index do |user, i| %>
<li class=<%= (i < 3 ? "foo" : "bar") %>>
<%= link_to user.username, user %>
</li>
<% end %>
Once you get to more complex things than i < 3 (like your 1..2 issue) you should think about a helper_method (in helpers) like class_by_position(pos) so that you can write
<li class=<%= class_by_position(i) %>>
The :first-child pseudoselector might be a better way to go, but you'll need to have a counter variable that keeps track of the iterations to do it your way.
Your question is a little vague. I can't tell if you want to stop processing the array after the first x, or not.
If you're just looking to stop after the first x items, or just looking for the 2nd and 3rd items the solution is to use a slice.
Example: just the first 3:
#user[0,3].each do |user|
... # only executed for user = #user[0],user = #user[1] and user = #user[3]
end
Example: just the second and third:
#user[1,2].each do |user|
... #only only executed for user = #user[1] and user = #user[3]
end
And here's a more specific answer to your question using these new concepts and the content_tag to programatically decide the class of the list item. If you're going to be doing this often, makes a great candidate for a function.
<% first = true %>
<% #user[0,2].each do |user| %>
<% content_tag :li,
:class => first ? "class-for-first-item" : "class-for-2nd-&-3rd" do %>
<%= link_to user.username, user %>
<% end %>
<% first = false %>
<% end %>
<!-- Now to do the rest of them:-->
<% #user[3,-1].each do |user| %>
<% content_tag :li, :class => "class-for-rest" do %>
<%= link_to user.username, user %>
<% end %>
<% end %>