Passing parameter to link_to rails 2 - ruby-on-rails

I wrote the following form:
<% remote_form_for :login,
:url => {:controller => :usuarios, :action => :login },
:html => { :multipart => true } do |f| %>
<p class="login_field">
Login:<br />
<%= f.text_field 'login' %>
</p>
<p class="login_field">
Clave:<br />
<%= f.password_field 'clave' %>
</p>
<br />
<p align ="right">
<%= f.submit 'Ingresar' %>
</p>
<p class="forgot">
<%= link_to "Olvid&oacute su clave?", { :controller => 'usuarios', :action => 'olvido_contrasena', :login => }, :post => true %>
</p>
<br />
<p id="error_msg_login"></p>
<% end %>
Now, In my controller I have:
def olvido_contrasena
if request.post?
u= Usuario.find_by_login(params[:login][:login])
puts u.email
if u and u.enviar_nueva_clave
flash[:message] = "Una nueva clave ha sido enviada a su correo electronico."
redirect_to :action=>'login'
else
flash[:warning] = "No se pudo enviar la nueva clave."
puts "fail"
redirect_to "/admin_main"
end
end
end
However, I have two problems:
The action is called as a GET (and it should be a POST).
The param[:login][:login] is not being sent....
What can I do here?
Thank you!
I solved my problem by adding a new view with a new form after the user clicks the "forgot password" link.
EASIEST and CLEANEST solution.

Basically -
You are clicking on link, which doesn't submit the form you have created, but "Submit" button can submit it.
As you are click a link, this is sending the GET request. If you want to send post request with form data, you may use, javascript event listeners to submit form on click of link.
As form is not being submitted, you are getting login[login] as nil.
To submit form with javascript you will be doing something like this with jquery -
$(".linkClass").click(function(event){
event.preventDefault(); //This will stop get request.
$("#formId").submit();
})

In your example code, the login-value is actually empty:
<%= link_to "Olvid&oacute su clave?", { :controller => 'usuarios', :action => 'olvido_contrasena', :login => }, :post => true %>
Also - "post => true" is not how to make it into a POSTed form.
Usually you'd use button_to (instead of link_to) but as you are already inside a form (and forms don't nest), you can fake a post by passing as a query string parameter the attribute "_method" (yes, it starts with an underscroe). so your example would become:
<%= link_to "Olvid&oacute su clave?", { :controller => 'usuarios', :action => 'olvido_contrasena', :login => #usario.login, "_method" => 'post'} %>
Now the problem is that the person is not already logged in... so you can't get their "login" - and the login field above the link is not part of the link. So you'll probably need to add some funky javascript to update the link field-value when somebody types something into the field.
... but your controller action should also deal with the case when somebody has not yet typed anything in. For example, if params[:login] is blank. it should render a "forgot your password? well enter your login name here" kind of page.

Related

Calling another controller inside a form in Ruby

In my app I have a case where a user can save a bill of lading from some form, or, send the same object to another controller.
My form is like this:
<%=content_for :detail do%>
<%=form_for #bill_of_lading,:url => bill_of_ladings_path(),:html=>{:class=>"form-horizontal bol-form"} do |f|%>
<%= render :partial => 'bill_of_ladings/form', :locals => {:f => f} %>
<div class="form-actions">
<%= button_to 'Create Draft', {:controller => "drafts", :action => "create", :bill_of_lading => #bill_of_lading }, :method=>:post ,:class=>"btn btn-warning"%>
<%=f.submit "Create Bill of Lading", :class=>"btn btn-primary","data-loading-text"=>"Saving..."%> or <%=link_to "cancel",bill_of_ladings_path,:class => "btn"%>
</div>
<% end %>
<% end %>
I want that, when the user press the "Create Draft" button, the data was sent to the DraftsController, the create method, passing the #bill_of_lading object.
But when I pressed the "Create Draft" button, it goes to the default submit button (in this case, to the bill_of_laddings_path).
So, how can I do the Create Draft button works as I want? (calling another controller, but passing the data as parameter)
Thanks

can't direct manual login away from sessions#create

Running Ruby 1.9.3p545 rails 4.1.4
I have an application where users canlogin through facebook, twitter, etc and can rehister manually. I would like a logon process for those who have registered manually.
Routes are
get 'auth/:provider/callback', to: 'sessions#create'
get 'auth/failure', to: redirect('/')
get 'signout', to: 'sessions#destroy', as: 'signout'
get "sign_up" => "profiles#new", :as => "sign_up"
get "log_in" => "logins#new"
post "log_in" => "logins#login"
Everything works fine except the manual logi. logins.new presents a form ok bu the subsequent submit always ends up in sessions controller at create.
I defined a login controller and tried to use the above post in the routes to get it away from the omniauth process in sessions#create.
The login form is
Log in
<%= form_tag sessions_path do %>
<p>
<%= label_tag :email %><br />
<%= text_field_tag :email, params[:email] %>
</p>
<p>
<%= label_tag :password %><br />
<%= password_field_tag :password %>
</p>
<p class="button">
<%= submit_tag "Sign in" %>
</p>
<% end %>
logins#login is
def login
authorized_user = Profile.authenticate(params[:name_or_email],params[:password])
if authorized_user
flash[:notice] = "Wow Welcome again, you logged in as #{authorized_user.username}"
redirect_to(:action => 'home')
else
flash[:notice] = "Invalid Username or Password"
flash[:color]= "invalid"
render "login"
end
Is tehre any way I can direct the submit of the login form away from the sessions controller?
Thanks in advance
end
The line
<%= form_tag sessions_path do %>
is what's throwing things off. It makes the form post to sessions_path. Try replacing it with <%= form_tag log_in_path do %>, or, better, yet, replace it with <%= form_tag "" do %> since the default is to post to the same URL as the current page.
Some more clarification:
<%= form_tag sessions_path do %>
generates the following HTML (roughly, skipping some details that aren't relevant to this issue):
<form action="/sessions" method="post">
since /sessions is the path to sessions#create. You want the action to be /log_in, i.e. the path to logins#login, so you want to change the argument you're passing to form_tag.
Since you're already on the page log_in, if you leave the action blank, i.e.:
<form method="post">
it will get you where you want, since the default behavior of the browser is to post to the same page.

Is it possible to make a link that functions as same as form does?

Now I have 2 forms that submit a comment.
Form Type A
<%=form_for(([#community, #comment]), :remote => true, :class => 'form' ) do |f| %>
<%= f.text_field :body, :id => "body", :class => "chat" %>
<button type="submit" class="btn">submit</button>
<% end %>
Form Type B
<%=form_for(([#user, #comment]), :remote => true, :class => 'form' ) do |f| %>
<%= f.text_field :body, :id => "body", :class => "chat" %>
<button type="submit" class="btn">submit</button>
<% end %>
Now, I want to have link_to button that functions as same as those forms do if a user clicks it.
When the user click on the link, #comment will be automatically filled just like below.
From Form Type A
#comment = "this is for community"
From Form Type B
#comment = "this is for user"
How can I do that? As far as I understand my situation.
Form is put type, then link_to is get type so it's impossible to re-use transaction of form.
Not sure what you mean by "transaction of form" but if you're asking if you can create/modify data via a single button or link than the answer is Yes, it is possible.
You can actually put with a link_to in rails ({:method => :put} (http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to)
If you want a button to do this you should checkout button_to (http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to)
It's better to use button_to.

How can I update the content of certain column without any page loading?

User has_one UserProfile.
Then UserProfile has wanted_message column as string.
Here, I'm showing input box to update wanted_message
I want it to be updated if certain user inputs any message then press "Update" button.
How can I? now, It's taking me to the url "/users/12" if I press "Update"
I don't want that:( I want it to be updated without any page loading(Ajax Request).
Then I want to have Action called update_message in User contoroller
How can I?
<%= form_for(current_user, :url => {:controller => "user", :action => "update_message" }, :remote => true, :class => 'form-search') do |f| %>
<%= f.fields_for :user_profile do |profile_form| %>
<div class="input-append">
<%= profile_form.text_field :wanted_message, :class => 'span6' %>
<button type="submit" class="btn">Update</button>
</div>
<% end %>
<% end %>
You have to set remote => true in your form and also set :method => put Put lets you update columns in your database and remote true will configure the form to send an ajax request. You'll also have to configure the update_message action in your controller to handle ajax requests. Finally, make sure your routes are configured correctly. You'll have to define that route in routes.rb and probably do an :as => 'update_message' to have access to that route helper method
This may help you with ajax in rails forms http://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html
Here's a sample form, it's in haml though:
= link_to "Start", polls_toggle_live_path(poll.id), :method => :put, :remote => true, :class=> 'btn btn-success btn-small start-poll', :id => poll.id
Which links to this controller action
def toggle_live
#poll = Poll.find(params[:poll_id])
#poll.toggle_live
#poll.save!
end
Calls this method in the associated polls model to switch the db column value
def toggle_live
self.is_live = !self.is_live
end
Finally its configured in routes.rb this way to pass along the correct updates
match '/polls/toggle_live/:poll_id' => 'polls#toggle_live', :via => :put, :as => 'polls_toggle_live'

Rails 3: Can't add correct route to legacy code

Believe you can help me.
I'm trying to add new functionality to legacy code (Typo). But it seems that there is some problem about routing.
In the project routes are generated the following way:
%w{advanced cache categories comments content profiles feedback general pages
resources sidebar textfilters themes trackbacks users settings tags redirects seo post_types }.each do |i|
match "/admin/#{i}", :to => "admin/#{i}#index", :format => false
match "/admin/#{i}(/:action(/:id))", :to => "admin/#{i}", :action => nil, :id => nil, :format => false
end
My functionality is about merging articles. For that I've added new action in the /admin/content controller:
def merge
#some code here
end
A piece of a view partial (_form.html.erb) added by me:
<% if current_user.admin? and !#article.id.nil?%>
<div class=''>
<h4><%= _("Merge Articles") %></h4>
<%= label_tag :merge_with, 'Article ID' %><%= text_field_tag :merge_with, nil, :size => 20 %>
<%= button_to 'Merge', admin_content_merge_path(:id => #article.id) %>
</div>
<%end%>
This partial is rendered by another partial (_edit.html.erb)
<%= form_tag(form_action, :id => "#{form_type}_form", :enctype => "multipart/form-data", :class => className) do %>
<%= render :partial => "form" %>
<% end %>
And finally _edit.html.erb is rendered by view new.html.erb
<%= render "admin/shared/edit", { :form_type => "article", :form_action => { :action => "new", :id => #article.id , :class => ('autosave')} } %>
The problem is how to write a correct route for the controller action above which will allow me to render an edit page containing newly merged article. I wrote:
match "/admin/content/merge/:id" => "admin/content#merge",:as => 'admin/content/merge'
rake routes output:
admin_content_merge /admin/content/merge/:id(.:format) {:controller=>"admin/content", :action=>"merge"}
But the new or edit action is being invoked as I can see.
Apparently, my route is wrong, isn't it?
Could you please help me with this.
Thanks in advance!
Update
Up-to-date new.html.erb:
<% #page_heading = _('New article') %>
<%= render "admin/shared/edit", { :form_type => "article", :form_action => { :action => "new", :id => #article.id , :class => ('autosave')} } %>
<% if current_user.admin? and !#article.id.nil?%>
<%= form_tag "/admin/content/merge/#{#article.id}" do %>
<h4><%= _("Merge Articles") %></h4>
<%= label_tag :merge_with, 'Article ID' %>:
<%= text_field_tag :merge_with %><br />
<%= submit_tag "Merge" %>
<% end %>
<% end %>
Read the hint from the course:
HINT:Nesting is invalid in HTML.
That means that you can't nest form tags, don't put the form tag in another form tag, your nested form wont be able to do a correct action.
Since you have to put your code at the end of the page, try and see how to do it with having your merging form tag below the main edit article form tag. So basically you can find where the big form tag ends and put it below it.
Try to see if you can figure it out, and if not, don't hesitate to ask :)
Btw. I think everybody had some problem with this

Resources