view contain all data from database - ruby-on-rails-3

i'm learning Rails 3, i'm generating a User, a User have many Post. but when i'm creating some Post all data from database appear like this in user/view/show.html.erb :
Post id: 2, title: "hello post", description: "hello posting", user_id: 2, created_at:"2013-03-01 16:18:07", updated_at: "2013-03-01 16:18:07"
my code in show.html.erb like this :
<%= #user.posts.each do |post| %>
<p>
<%= post.title %>
</p>
<p>
<%= post.description%>
</p>
<% end %>
how to hide all post data from database? Thanks..

The problem is that you're using the <%= %> embed rather than <% %> for your loop (<%= #user.posts.each do |post| %>). The loop returns the array of Post objects, and then your use of <%= tells erb to stick that value into the page.
You want to use <% #user.posts.each do |post| %> instead (without =). That means to execute the code, but not display it's result.

Related

Rails - SQL injection using .order to filter an index

In my index view, I'm iterating over a list of bookings.
Also, I added a dropdown menu with the option to sort by created_at: asc and created_at: desc.
index.html.erb
<div class="dropdown">
<button class="btn" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Sort by
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<p> <%= link_to "ASC", sort: :asc %> </p>
<p> <%= link_to "DESC", sort: :desc %> </p>
</div>
</div>
<% #bookings.each do |booking| %>
<%= booking.address %>
<%= booking.created_at %>
<% end %>
This is the way I am sorting the #bookings in the controller:
booking_controller.rb
class Users::BookingsController < ApplicationController
def index
#bookings = current_user.bookings.order(created_at: params[:sort])
end
end
I'm not really sure if this is the best solution and if it has some vulnerability in terms of SQL injections...
Generally using params for order is unsafe, see https://rails-sqli.org/#order
You can use sanitize_sql_for_order to sanitaze input for ActiveRecord#order
Passing key/value pairs to order(created_at: params[:sort]) is safe. Rails validates the direction. If you give it an invalid direction it will raise ArgumentError: Direction "..." is invalid. It's been this way since the syntax was introduced in Rails 4.
Passing a string to order as in order("created_at #{params[:sort]}") could be exploited in Rails 5 and earlier. See Rails SQL Injection for details. Rails 6 now sanitizes order arguments and will raise an exception if it detects funny business.
Rails 6, in general, is more robust against SQL injection. But it's up to you to sanitize your inputs before passing them to anything which accepts raw SQL.
Your view is not turning the bookings into a drop down menu. Instead, it's just a bunch of text. As lurker suggested, use a function like collection_select to generate the select and option tags for you.
<%= form_for #user do |f| %>
<%= f.collection_select :booking_id, #bookings, :id, proc { |b| "#{b.address} #{b.created_at}" , prompt: true %>
<%= f.submit %>
<% end %>
To tidy that up a bit, you can add a method to Booking to produce the label you want and replace the proc.
class Booking
def dropdown_value
"#{address} #{created_at}"
end
end
<%= form_for #user do |f| %>
<%= f.collection_select :booking_id, #bookings, :id, :dropdown_value, prompt: true %>
<%= f.submit %>
<% end %>

Stuck on linking to a url in the database, Rails

I tried both these:
<% #candidates.each do |candidate| %>
<h4> <%=candidate.full_name %></h4>
<p>Links: <%= link_to "facebook", "#{candidate.link1}" %> </p>
<% end %>
<% #candidates.each do |candidate| %>
<h4> <%=candidate.full_name %></h4>
<p>Links: <%= link_to "facebook", "candidate.link1" %> </p>
<% end %>
With the first one, the string interpolation, I get returned an facebook, ignoring the second part of the link_to altogether.
With the second one, where the link1 is an attribute of the class Candidate, I get an error No Route matches candidate.link1.
What syntax do I need so the second part of the link_to is seen as a url in the database (in this case: "https://facebook.com/......") instead of a route?

I am new on rails i not sure what is going on my code but I want to filter data from database by searching using id how can i do it

I am trying generate a code that tracks for documents that revolve within the organisation. I have done other codes for adding employees, adding document types and logging in now I am struggling on creating a document form and search from the document that I have created. This code is for searching:
controller#show
def show
#generate_documents = GenerateDocument.where('Reciever LIKE?',"%#{params[:search]}%")
# #generate_documents = GenerateDocument.all
end
views/show
<%= form_tag generate_document_path, :method => :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search" %>
</p>
<% end %>
<!-- end of seaerch form -->
<!-- loading data from database and displaying then in a list format BEGIN -->
<ul>
<% #generate_documents.each do |generate_document| %>
<li>
<%= link_to generate_document.Reciever, edit_generate_document_path(generate_document) %>
</li>
<% end %>`enter code here`
</ul>
<!--
END LISTING -->
<%= link_to 'New Generate Document', new_generate_document_path %>
Even Iam new to rails, but i can help you with basics that you need to pass the parameters from the view to the controller, therefore you can use:
:url => {:controller => "name_of_your_controller", :action => "action_to_be_perforemed", :id => "whatever id you want"}
or else you can also pass the object within the url like we do while edit request
<%= link_to "Edit", edit_post_path(#edit)%>
which will give the :id of the particular post.
Hope this may help you.

Rails search functionality

I am taking a rails class at my University and I am trying to create a search form which will show the results on the same page rather than show a different page of results. Is this something simple to do? I am creating a museum app with artifacts for each museum but I want the user to search artifacts from either page.
On my routes.rb I have
resources :artifacts do
collection do
get 'search'
end
end
On my museum index I have the code below that he gave us but not sure how to tweak the get routes for the same page.
<%= form_tag search_artifacts_path, :method => 'get' do %>
<p>
<%= text_field_tag :search_text, params[:search_text] %>
<%= submit_tag 'Search' %>
</p>
<% end %>
<% if #artifacts %>
<p> <%= #artifacts.length %> matching artifacts. </p>
<h2> Matching Artifacts </h2>
<% #artifacts.each do |a| %>
<%= link_to "#{a.name} (#{a.year})", a %><br />
<% end %>
<% end %>
Yes, this is easy. Just have the index page return the search results if params[:search_text] is present - this way you don't need a new route or a different page.
class ArtifactsController < ApplicationController
def index
#artifacts = Artifact.search(params[:search_text])
end
end
class Artifact < ActiveRecord::Base
def self.search(query)
if query
where('name ILIKE ?', "%#{query}%")
else
all
end
end
end
So then your form looks like:
<%= form_tag artifacts_path, :method => 'get' do %>
<p>
<%= text_field_tag :search_text, params[:search_text] %>
<%= submit_tag 'Search' %>
</p>
<% end %>
Edit:
So what you really want to do is any page you want to search, include a form which makes a request to that same page.
Then in each of those controller methods just put this line of code:
#artifacts = Artifact.search(params[:search_text])
and that will populate the #artifcats array with only artifacts that match the search query.
Try using "Ransack" gem. It can also perform some more powerful searches.

Rails 3 form only returning last element

I'm trying to build a form that will list all users and allow you to check the ones that you want to add to a team. Here's my first cut at the form:
<div id="add_team_mates">
<%= form_tag do %>
<%= will_paginate #users %>
<ul class="users">
<% #users.each do |user| %>
<li>
<%= gravatar_for user, :size => 30 %>
<%= link_to user.name, user %>
<%= check_box_tag("add", user.id) %>
</li>
<% end %>
</ul>
<%= submit_tag "Add Team Mates", :action => "add_team_mates" %>
<% end %>
</div>
And, right now this is all that I have in the controller:
def add_team_mates
end
The problem is that if I check multiple users, I only get the last user.id rather than multiple is as I'd expect. Here's some example from the log:
Started POST "/teams/5" for 127.0.0.1 at 2011-04-14 15:28:13 -0700
Processing by TeamsController#add_team_mates as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"IHFDevfKES8NibbCMlRa1t9qHn4/ZMKalK1Kjczh2gM=", "add"=>"3", "commit"=>"Add Team Mates", "id"=>"5"}
Completed in 12ms
Any help on this would be greatly appreciated. Thanks!
All your checkboxes have the same name, change the line to
check_box_tag("add[]",user.id)
In the controller your parameters will be like so:
params[:add] = ['foo','bar','baz']