At this time I need to get and id value from an association
Because I create a new note, but i can assign this note to whoever i want, then I have it this way
<%= f.association :user,
:label => false,
:selected => current_user.id,
:required => true,
:input_html => {
:class => 'span4',
:disabled => true,
:style => "float:right",
:id => "usuario"} %>
And the controller create method is this way
def create
#note = Note.new(note_params)
#note.user_id = params[:user]
render :action => :new unless #note.save
end
But when I press the submit button everything save unless the value for the column :user_id
I have tried with params[:user_id] but it doesn't work
Thanks for your help and sorry for my english
First you need to remove the attribute disabled from your field, a disabled field isn't sended by your form (look at Disabled form fields not submitting data).
And, your user_id should be placed in something like params[:note][:user_id], take a look at server log and search for user_id right after you send a POST to server, there be something like:
Started POST "/note" for ::1 at 2013-07-18 15:22:34 +0000
Processing by NoteController#create as */*
Parameters: {"note"=>{..., "user_id"=>"1", ...}}
Related
I'm trying to send an email to the client when he successfully makes a transaction using paypal.
I've already manage to send the custom email parameter to paypal in a custom parameter they provide.
What I have right now
My product model:
class Product < ActiveRecord::Base
# This defines the paypal url for a given product sale
def paypal_url(return_url, cancel_return, useremail)
values = {
:business => 'your_business_email#example.com',
:cmd => '_xclick',
:upload => 1,
:return => return_url,
:rm => 2,
:cancel_return => cancel_return,
:custom => useremail
}
values.merge!({
"amount" => unit_price,
"item_name" => name,
"item_number" => id,
"quantity" => '1'
})
# For test transactions use this URL
"https://www.sandbox.paypal.com/cgi-bin/webscr?" + values.to_query
end
has_many :payment_notifications
end
here, I'm passing a parameter for the :custom object which I have it hardcoded in the button link_to helper here:
<%= link_to 'checkout', #product.paypal_url(payment_notification_index_url, root_url, 'testing#testing.com') %>
This works perfectly, and I am able to store the custom email in the database:
class PaymentNotificationController < ApplicationController
protect_from_forgery except: [:create]
def create
# #payment = PaymentNotification.create!(params: params, product_id: params[:invoice], status: params[:payment_status], transaction_id: params[:txn_id] )
#payment = PaymentNotification.create!(params: params, product_id: 1, status: params[:payment_status], transaction_id: params[:txn_id], email: params[:custom] )
# render nothing: true
if #payment.status == 'Completed'
PaymentTransactions.success(#payment).deliver_now
redirect_to root_url, notice: 'Success!'
else
redirect_to root_url, notice: 'Error'
end
end
end
Question
How do I get the client to input their email in a field and pass that value into the parameters of the link_to so that paypal return the email so I can store it in the database and send an email to the client?
Thanks
You should not use link_to, but form_tag with method: :get
<%= form_tag (#product.paypal_url(payment_notification_index_url, root_url, :custom)),method: :post do %>
<%= text_field_tag :custom %>
<%= submit_tag 'checkout' %>
<% end %>
This might be more than what you're expecting...but read on.
Before you dive further into the implementation, keep in mind that, you're using the sandbox version of Paypal for testing, and in production, you'd want the paypal_url to return an encrypted url for the user as to avoid tampering of the transaction, such as changing the price (more details at Railscast #143).
Now, realize that any approaches on the client-side via javascript to get the user email field and modify the link will not be secure as the link should be generated from your server after encryption (and you'd need to pass in the user email as part of the call).
So, what can you do? Use ajax to send the request to the server containing the parameters (e.g. return_url, user_email, etc..), and respond in the server with an encrypted link. Then, you can use javascript to replace the link and allow user to click that instead.
As you realize, the implementation above is very general and any answer would not suit your specific case. You should keep the above in mind as you'd be required to do that anyway down the road.
I'm having a problem with submitting a simple form, and I'm not entirely sure what the deal is. The problem, I think, is that I'm trying to submit a form from a User's profile page to another model (ItemShare). Instead of submitting the form via post, it's trying to make a GET request. When I've changed the ItemSharesController to allow for this, it puts ItemShare#index into my modal form, even though I've specified in a billion places that I want it to post. POST!
In my routes.rb:
match '/item_shares' => 'item_shares#create', :via => :post
resources :item_shares, :except => :create
The form:
#share-list-button-dialog.modal.hide.fade{:role => "dialog"}
.modal-dialog
%h3 Share List
.modal-body
=form_for(ItemShare.new, :method => :post, :url => {:action => "create"}) do |f|
=f.hidden_field(:item_id, :value => item.token)
=f.hidden_field(:owner_id, :value =>user.id)
=f.label :shared_user_email, "Your collaborator's email:"
=f.text_field :shared_user_email, :value => "collaborator#example.com"
=f.submit "Share"
ItemSharesController:
class ItemSharesController < ApplicationController
def new
#item_share = ItemShare.new
end
def create
#item_share = ItemShare.new(params[:item_share])
respond_to do |format|
if #item_share.save
format.html {redirect_to user_path(current_user.id), :notice => "List shared successfully"}
else
flash.now[:alert] = "Could not share list."
end
end
end
end
And this is what the stack trace is showing:
Started GET "/item_shares/" for 127.0.0.1 at 2013-10-15 21:40:44 -0400
ActionController::RoutingError (No route matches [GET] "/item_shares"):
actionpack (3.2.11) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
...
What's going on here??
UPDATE ... finally know what was up.
The form itself was not the problem, but the button I was using to trigger the modal form. I had:
%button{'data-toggle' => 'modal', 'href' => '../item_shares/', 'data-target' => '#share-list-button-dialog'}.
Changed it to this:
=button_to "Share", item_shares_path, "data-toggle" => "modal", "data-target" => "#share-list-button-dialog"
And now it's all working fine. Many thanks to Helios de Guerra for his help and patience. :)
From what you're describing, you should just be using the standard conventions.
Routes:
resources :item_shares
Form:
<%= form_for(ItemShare.new) do |f| %>
...
<% end %>
If it doesn't work, check the source of the rendered page. The form markup should include something like:
<form accept-charset="UTF-8" action="/item_shares" id="new_item_share" method="post">
Upon first glance, I'd say it has something to do with this =form_for(ItemShare.new
In my experience, Rails builds the path from the url in the form_for, which means that yours is going to be messed up with that. You might want to give this a try:
#users/new
def new
#item_share = ItemShare.new
end
#form
=form_for(#item_share
I'm not totally sure on it, but it's my hunch
I am trying to write an Rspec test to test one of my controllers in Rails but I am having a problem getting the correct params hash.
My create method in my Activities Controller looks like this(The update method is identical). As you can see the params hash it receives has an :activity, :start_time, and :end_time hash.
def create
#activity = Activity.new(params[:activity])
#activity.start_time = to_interval(params[:start_time])
#activity.end_time = to_interval(params[:end_time])
respond_to do |format|
....
The rspec activities controller spec looks like
it "redirects to the activity" do
activity = Activity.create! valid_attributes
put :update, :id => activity.id, :activity => valid_attributes
response.should redirect_to(activity)
end
The second line calls valid attributes
def valid_attributes
FactoryGirl.attributes_for(:activity)
end
which returns a hash
{"id"=>"1", "name"=>"Some Activity1"}
and when the controller receives it the hash looks like
{"activity"=>{"id"=>"1", "name"=>"Some Activity1"}, "controller"=>"activities", "action"=>"create"}
As you can see the :start_time and :end_time hashes are missing. In the end I need a hash which looks like
{"activity"=>{"id"=>"1", "name"=>"Some Activity1"}, "start_time"=>{"hours"=>"1", "minutes"=>"0"}, "end_time"=>{"hours"=>"1", "minutes"=>"0"}, "controller"=>"activities", "action"=>"create"}
I cannot figure out the correct syntax for adding the :start_time and :end_time hashes to the params hash. I cannot combine it with the hash returned from FactoryGirl because the create method combines the three hashes into the form below which is incorrect because now :start_time and :end_time are embedded in the :activities hash.
{"activity"=>{"id"=>"1", "name"=>"Some Activity1", "start_time"=>{"hours"=>"1", "minutes"=>"0"}, "end_time"=>{"hours"=>"1", "minutes"=>"0"}}, "controller"=>"activities", "action"=>"create"}
Any help or hints are appreciated and I thank you for you time and help!!
I find something weird in your code. You are trying to put :update, but you're looking at the create action (which may also be somethings that contributes to the issue, your test for the create action could already have the params.)
For your question, you should be able to do this to pass the start_time and end_time parameters
put :update, :id => activity.id, :activity => valid_attributes, :start_time => { :hour => 1, :minute => 2 }, :end_time => { :hour => 1, :minute => 2 }
I have a edit form for #users.
In there I have a text_field :username
<%= form_for #user, :url => { :action => "update" } do |f| %>
<%= render 'shared/error_messages', :target => f.object %>
<div class="field">
<%= f.label :username %><br />
<%= f.text_field :username %>
</div>
In my User model I use the friendly_id gem, set to :username as well. So my urls look like domain.com/users/:username instead of :id.
has_friendly_id :username
Now in my application layout, I also use #user.username in my navigation to link to the profile.
All works well, EXCEPT if I leave my :username field empty on save. It fails to save cause of validations,
validates :username, :presence => true, :uniqueness => { :case_sensitive => false }, :length => { :maximum => 50 }
and tries to render "edit" again. But to render "edit" we need the username to create the link in the navbar. And apparently it's passed on as username => "", even though it rightfully so failed to save and proper validations are in place.
def update
#user = current_user
if #user.update_attributes(params[:user])
flash[:success] = "Account updated."
redirect_to :back
else
#title = "Edit"
render "edit"
end
end
So I end up with a RoutingError:
No route matches {:action=>"show", :controller=>"users", :id=>#<User id: 6, username: "", persistence_token: "c2f2545659c186131537155347f46f7da5eb0d51b27707e71da...", created_at: "2011-03-14 14:26:48", updated_at: "2011-03-15 01:54:33", email: "test#test.com", crypted_password: "0d6489b1447d278bc4f7c86bab13787f226a10a302b43ec02ff...", password_salt: "Lq2G80iSVeaitB5PDwf", perishable_token: "Tm7Jzyq8QutfaxL3JLZ8", active: true>}
First of all, redirecting to :back, even if you successfully change the username, will likely fail because the URL itself is going to be different. So you should probably do
redirect_to #user
instead.
If you want to use the username field as the basis of a friendly_id, then it's probably best to not let it be blank, which you could enforce by adding a validation to the model:
class User < ActiveRecord::Base
...
validates_presence_of :username
...
end
Alternatively, if for some reason in your app makes sense to have them blank, you can force Rails to generate the URL based on the numeric id rather than the friendly_id in these cases.
To do this, you would need to set username value to nil rather than blank, and then either do
redirect_to #user
or
redirect_to user_url(#user)
In this case you'll also want to use the :allow_nil => true option to has_friendly_id.
I'm the author of FriendlyId, if this doesn't solve your problem feel free to send a message to FriendlyId's Google Group or to me personally at norman#njclarke.com, and I'll try to help you out.
You don't really need to re-render the edit screen if your validation fails.
It'd probably work better if you updated your page using ajax and use a remote_form_for (Rails 2) or form_for :remote => true (Rails 3) when submitting your form. That way if your form passes the validation you can just redirect the user like you're trying to do, but you don't need to actually leave the page if your validation fails, you can just send the validation message back to the form.
Simone Carletti's blog has a pretty decent example on how to do it.
http://www.simonecarletti.com/blog/2010/06/unobtrusive-javascript-in-rails-3/
Ryan Bates has put up a simple example of how to use it as well.
http://railscasts.com/episodes/205-unobtrusive-javascript
I'm trying to use rails to change a textfield's value with a link_to_remote
<%= link_to_remote address.street, :url => {:controller => 'incidents', :action=>'street_selected', :update => "street.value" } %>
Street is the id of the textfield
my controller function renders text, but the textfield value isn't changed. How do i get this to work?
You could either remove and replace the text field or just update the value. Updating the value itself probably much simpler. The following assumes you haven't switched out Prototype for jQuery or another JS toolset.
In the view:
<%= link_to_remote address.street, :url => {:controller => 'incidents',
:action=>'street_selected'} %>
In the controller
def street_selected
...
code that gets new value
...
respond_to |format| do
format.js { render :update do |page|
page <<"$('textfield').value = new_value
end
}
end
P.S. You might want to pass some parameters in that remote link to allow for dynamic processing. Otherwise there's no point in doing this with AJAX.