Pass data safely from view to controller in rails - ruby-on-rails

I want to pass data from a view (link) to a controller so it can look up the related information. Services for a company, in this case.
I see examples where people have added to params like this:
<div>
<%= link_to 'Services', :controller => 'company', :action => 'services', :company_id => #company.id %>
</div>
...but that results in a transparent (unsafe) URL like this:
http://localhost:5000/company/services?company_id=17
Is there a way to get around this without stuffing data into the Session? What's the best practice on links inside an app that requires authentication?

THere is no such major harm in passing data like this in View.
Still if you insist on having, then check prettyurls:
http://railscasts.com/episodes/314-pretty-urls-with-friendlyid
Prior to we must have valid checks in controller & model files.
1. Valid Checks and redirection in Controller is helpful.
2. Depending on need adding validations in model can be a good support.

<%= link_to "Sign in", new_session_path(:id => Base64.encode64("1")) %>
and in your controller
def new
id=Base64.decode64(params[:id].to_s)
end
this is another form for create a link with data
check your routes with command un console rake routes
for more information read this documention
http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to

Related

How do rails forms work without a model?

I am trying to challenge my learning by creating a simple project using rails forms, however I have gotten really stuck and can't find any information that seems to help online.
What I am trying to do:
I want to create a rails application with no model (so no persistence of data). Simply put I want a user to enter a Soundcloud URL which then gets transferred to the controller where I can do more logic. Essentially I am really trying to understand the connection between the Rails form and the controller in rails. I have spent all day reading about HTML forms, as well as googling this exact question without really fully getting it.
I understand there are different form helpers, but what I cannot seem to understand is how to use these without a model. My biggest hang up right now is I cannot get the form values transferred to the controller. I thought I understood RESTful routes, PUT/GET etc.. but this has made me super frustrated that I cannot seem to get my head around this. Any advice is super appreciated.
The code:
Below is the specific code I am struggling with, currently when I get submit the form it crashes giving me an error based on routes, and that's where I am stuck.
Problem code is found in the _form.html.erb file in views:
<%= form_tag '/show' do %>
<%= label_tag(:soundcloud_url, "Please enter a valid Soundcloud Artist URL:") %>
<%= text_field_tag(:soundcloud_url) %>
<%= submit_tag("Let's go!") %>
<% end %>
Routes.rb:
Rails.application.routes.draw do
resources :soundcloud_query
root 'soundcloud_query#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Error:
Routing Error
No route matches [POST] "/show"
rake routes output:
Prefix Verb URI Pattern Controller#Action
soundcloud_query_index GET /soundcloud_query(.:format) soundcloud_query#index
POST /soundcloud_query(.:format) soundcloud_query#create
new_soundcloud_query GET /soundcloud_query/new(.:format) soundcloud_query#new
edit_soundcloud_query GET /soundcloud_query/:id/edit(.:format) soundcloud_query#edit
soundcloud_query GET /soundcloud_query/:id(.:format) soundcloud_query#show
PATCH /soundcloud_query/:id(.:format) soundcloud_query#update
PUT /soundcloud_query/:id(.:format) soundcloud_query#update
DELETE /soundcloud_query/:id(.:format) soundcloud_query#destroy
root GET / soundcloud_query#index
Github link:
https://github.com/gaelant/simple_soundcloud_app/commit/09c4c4df524bb721a0f472b4378cd8c1ff18177f
Note: I understand this is a basic question but I have just gotten really confused with this. I know the way the code above is written is not correct, but I have tried so many different things and I just don't understand what is going on, or if this is even possible without a model.
Your /show form action points to nowhere. rails routes shows you which url is valid and to which controller#action each of them lead.
The correct form action would be
<%= form_tag '/soundcloud_query' do %>
<%= label_tag(:soundcloud_url, "Please enter a valid Soundcloud Artist URL:") %>
<%= text_field_tag(:soundcloud_url) %>
<%= submit_tag("Let's go!") %>
<% end %>
A far more better way is to use the url_helpers available through your defined ressource in Routes.rb
Doing so your form action would look like this
<%= form_tag soundcloud_query_index_path do %>
<%= label_tag(:soundcloud_url, "Please enter a valid Soundcloud Artist URL:") %>
<%= text_field_tag(:soundcloud_url) %>
<%= submit_tag("Let's go!") %>
<% end %>
The hardcoded and the url_helper based solution will route your request to a controller class named SoundcloudQuery where the action create will be called. Inside this action you have to put all needed logic.
It's also possible do define that /show should point to a specifc controller and action. This would look like this.
post '/show', to: 'mycontroller#myaction', as: 'mypathnameforhelper'
A much more better explanation with many examples about routes and how to use them can be found in this quite good guide.
Rails Routing from the Outside In
Hint: You should stay close to the ROR naming conventions. Controllers should have pluralized names. So you should define your routes like this:
Rails.application.routes.draw do
ressources :soundcloud_queries
root 'soundcloud_queries#index'
end
and then rename your controller class and file accordingly into SoundcloudQueries and soundcloud_queries.rb. But this is not mandatory.
I think in this case you should not use the url in the form_tag but the controller action.
Let's say you've got a view called my_form.html.erb and a submit_form method in your soundcloud_controller.rb
def submit_form
params[:soundcloud_url] your logic
end
I'd set up the routes like this:
get 'soundcloud_query' => 'soundcloud_query#my_form' // didn't want to use 'resources' but it doesn't matter
post 'soundcloud_query' => 'soundcloud_query#submit_form'
The form would then look like:
<%= form_for :this_doesnt_matter, action: :submit_form do |f| %>
<%= f.text_field :soundcloud_url %>
<%= f.submit %>
<% end %>

How to create a href tag with link_to and action 'create'

I want to create a href tag like href=contacts/create. In my contacts_controller, I have a create GET action. I know this is against rails convention. I still need to create the above link using options = {controller=> 'contacts', action=>'create'}. It works for any other arbitrary action name
You can the hardcoded path option:
<%= link_to "Create", "contacts/create" %>
or the Rails generated path option:
<%= link_to "Create", { controller: "contacts", action: "create" } %>
This is not just against Rails' convention, but against sounds HTTP usage. This often causes serious problems that you can't predict in advance. Web crawling is just one of them, where something like the Google bot accidentally creates a new contact in your database, simply by crawling the page. Or script kiddies who find you have a create link, and send 100,000 clicks to it in quick succession.
Numerous other issues happen like this, including, at one well-known time, Google Chrome pre-fetching GET urls from the page to "speed up the user experience"; this was felt far and wide by sites that had used this technique. It's not an idle warning or a style issue: this can have a disastrous impact on your site.
First off this is really bad idea since GET requests should be idempotent. You're not just flouting convention - you're setting yourself and your users up for a really bad time since for example pressing the back and forward buttons will cause resources to be created - over and over. And there is guaranteed a better way to solve whatever you are trying to do such as:
# a "discrete form"
<%= button_to "Create contact", contacts_path, method: :post %>
# or use the rails ujs
<%= link_to "Create contact", contacts_path, method: :post %>
If you ABSOLUTELY have do this:
Rails.application.routes.draw do
get "contacts/create"
end
You can now do:
<%= link_to "Create", { controller: 'contacts', action: 'create' } %>
Congratulations, you broke the internets.
Like you mentioned, this is against rails convention, but if absolutely necessary, you can do this from your controller:
options = {controller=> 'contacts', action=>'create'}
view_context.link_to url_for(options)
If you need the href to only be the path, you can do:
options = {controller=> 'contacts', action=>'create'}
view_context.link_to url_for(options.merge(only_path: true))

Getting parameters of one view in another

I am completely new to RoR. I have a parameter in one view of a controller now how can i get it in another view of the same controller?
You can set up a form or a link_to in form-a and make a HTTP (POST/GET) to form-b. Remember that you can put also any HTML (or JS) in your view that you like.
Have a look at:
link_to
link_to "Profile", :controller => "profiles", :action => "show", :id => #profile
# => Profile
If you want to link to a associated table you can easy do this with:
# #person.company.name is the name of the link
# company_path(#person.company) is the associated model
<%= link_to #person.company.name, company_path(#person.company) %>
I approve you to read the ruby on rails guides
Read the getting started chapter and then create the blog application you will see
that gives you a great entrace to ruby on rails.
Try to understand the Rails way.

Ruby On Rails: using arrays with link_to

I was curious on how to use arrays in the link_to method in ruby on rails for example:
Controller:
def index
#test = [1,2,3]
end
View:
<%= link_to "test", {:action => 'index'}, :test => #test %>
When looking at the source then, I end up with something to the effect of:
test
My guess is that the array's to_string or something similar is getting called to set the value of test in the html.
My goal is to be able to have a form in which people can submit data on the page, and then once they've submitted the data and return to the page, if they click on the link the data will persist through clicking on the link.
*Ideally I would like to do this without having to pass the parameters in the url.
Thank you.
If you want to keep data you should probably use cookies. They are very easy to use, just assign a value with the following in the action:
cookies[:some_key] = "some value"
and retrieve it with this:
cookies[:some_key] # returns "some value"
However, just to clarify what link_to is doing in your example:
<%= link_to "test", {:action => 'index'}, :test => #test %>
When looking at the source then, I end up with something to the effect of:
test
The reason is that you are passing #test to the third argument in link_to, which is a hash of html attributes, hence why it's turned into one. To have it become an parameter on the link, you need to pass it with the second, eg, {:action => 'index', :text => #test}. As noted above, however, this is not necessarily the best way to tackle this and, in addition, it's usually best to also pass the controller name to link_to or, better yet, use a named route.
If I understand well, you want to keep the datas submitted by the user after they validate the form ?
Well Rails is able to do that without any of your code line needed.
Based on the supposition that you have a route resource "objects"
In your controller :
def edit
#object = Object.find_by_id params[:id]
end
def update
#object = Object.find_by_id params[:id]
if #object.update_attributes params[:object]
# The datas have been successfully saved. You redirect wherever you want to.
else
render :action => 'edit'
end
end
and in your view :
<% form_for #object do |f| %>
<%= text_field :name %>
<% end %>
When the form fails to validate, the "name" text field automatically gets the previous entered data.
If after that you still need to reload your datas, you don't need to add them as a parameter in a link tag.
You get the object in your controller and passes it's datas to the view where you display it.
I would just write a view helper that formats it into a string with good separators, like commas.
That isn't a good way to be passing along information though. Try session variables, cookies, or url-encoded variables instead.
The best match to what you are doing would be url-encoded variables, which will show up in a form similar to this:
test
My guess is that it is using Array#join.
You could try something like
:test => #test.join( ',' )
and then parse the string in your controller. But it is somewhat error prone if the user enters the same character you chose as delimiter.
But, assuming the linked page is also served by Rails, I think the best solution would be to use the flash area to store the results on the server
flash[ :submitted_params ] = params;
and in the controller for the linked page
old_params = flash[ :submitted_params ] || {}

Ruby on Rails passing of parameters between views from link_to tag instead of submit_tags (having both on page)

I'm creating in my index page of my ruby on rails program, a list of the most commonly searched for terms in my database and hence each time a user selects a specific category this is written to another database.
What i would like it to create a hyperlink and pass a certain amount of parameters to a form like is usually done with a select_tag but instead with just a hyperlink, i would like to pass a set of hidden fields that i have on the page as well as what the user has selected.
To give you a better idea, basically i have the following structure in my program:
User inputs a search on (index.html.erb), user clicks on submit tag
action, user is taken to search.html.erb page and is displayed a set of refined categories + some fields, submit button,
user is taken to closest.html.erb (which uses parameters from the previous form by invoking the params[:searchSelected] and a few other params. )
I would also like to add this functionality:
Mimick this same operation, but instead of going in the search.html.erb, i would click on an already refined search category on the index.html.erb page (from a link_to , transmit as parameters which link_to the user has chosen + the hidden fields.
i Currently have this code
#stats.each do
|scr|%>
<%= link_to scr.category, :action => 'closest', :id => scr.category%>
I'm not sure if this is relevant, but i currently have the following routes in my routes.rb file
map.resources :stores, :collection => { :search => :get }
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
would anyone please assist me please? this is my first ruby on rails project and i would really like to find a way around this please
I am not sure if this is what you were thinking, but you can add additional parameters to the link_to tag. They are then available in your controller. So:
<%= link_to scr.category, :action => 'closest', :id => scr.category, :other_param => "test" %>
Will be available in your controller.
def closest
params[:other_param] == "test" #this will be true
end
i managed to resolve this by taking the params[:id] and then according to the value either set my own values (instead of the hidden ones in the index.erb which i had set manually anyway) and otherwise, continue as usual had i placed a regular search
View:
<%= link_to obj.ptc_devicename ,"/wiuconfig/hd?idval=#{obj.id.to_s}&val=#{#devicetype}",:value => obj.ptc_devicename,:id =>obj.id %><br/>
Controller:
#Heading= params[:val]
#id=params[:id]
value will be id is 2 and val is #devicetype

Resources