assigning parameters to a model in a link_to helper - ruby-on-rails-3

if am trying to pass a parameter through a link and assign it to a specific model. here is the code i'm working with:
<%= link_to ( image_tag("item.png", :size => "50*50", :border=> 0, :alt => "item", :title => "item"), {:action => 'initialize_order', :frame_id => 1 }) %>
right now :frame_id is getting passed through as:
{"frame_id"=>"1"}
i want the parameter to be assigned to the model :order, returning:
"order"=>{"frame_id"=>"1"}
i know the answer must be simple but i've searched for a while now.

try this in your url args:
{:action => 'initialize_order', :order => {:frame_id => 1 }}
alternatively, since you only have one parameter, just pass it as :id and assign it in the controller.
Even better, build your app using RESTful routes, with an orders_controller and an initialize method. If orders and frames have a parent-child relationship, then nest them in your resources. That way you can use all the path generators.

Related

Auth Failure in Form

Rails has generated this action url for my form:
<form action="/auth/failure?action=update&controller=users"...
I'm authenticated to the website, even If I shouldn't be, it would redirect somewhere as I understand Auth.
My Form code:
<%= form_for #user, :url => { 'controller' => 'users', 'action' => 'update'} do |f| %>
Thanks!
There is two thing you have to know
Ruby makes difference between symbols (:controller, :update) and strings ('controller', 'update').
You do not need to specify :url in this case.
So, for your current code, the correct line is simple:
form_for #user do |f|
If #user is a new record, form_for will point to create action of your UsersController, if #user is an existing record, form_for will point to update action automatically. Rails is smart enough to do this :-)
If you really want to use :url attribute of form_for, you have two option:
Use routing helper methods: form_for #user, :url => user_path(#user), :method => :put
Use a correct path hash: form_for #user, :url => { :controller => :users, :method => :update, :id => #user.id }
Rails uses REST style for building urls if you use resources :users in config/route.rb (and I recommend you to use that), and it have two thing you need to know:
- Collection is a group of entities (in your case, users)
- Member is one entity
So collection URL is something where you can expect multiple entities, member URL is something where you can expect only one entity.
You must use :id when you describe update action with URL-hash, because update can done only on member, not on collection. So you have to build a member URL with a special HTTP method (PUT) to clarify, what do you want to do.

url_for adding controller and action to querystring in rails 3.2

I am trying to generate a url in an actionmailer template. An example if the url I want to generate is
http://0.0.0.0:3000/users/confirm/lNbQxzFukYtEEw2RMCA
Where the last segment is a hash to identify the user
However when I use this
<%= url_for(:controller => 'users', :action => 'confirm', :id => #user.confirmhash, :only_path => false) %>
It generates this
http://0.0.0.0:3000/assets?action=confirm&controller=users&id=ZOR3dNMls8533T8hJUfCJw
How can I get it to correctly format? I have no idea where 'assets' is coming from.
Is there an easier way to use named routes that I am missing?
I've found the answer. As I'm still learning I've missed the option to create a named route. So this this the path I've taken.
In config/routes.rb
match 'user/confirm/:id' => 'users#confirm', :as => :confirm_account
Then in my action mailer template I've used
<%= link_to "Confirm your account", confirm_account_url(#user.confirmhash) %>
Which passes the :id into the controller action.

Rails simple_form pre-populated input values lost during server side form validation [duplicate]

This question already has an answer here:
Rails simple_form server side validations lost URL params
(1 answer)
Closed 8 years ago.
I have a simple_form in my rails app that I want to pre-populate
some of the fields with URL parameters.
Example URL is:
http://localhost:3000/surveys/new?phone=8675309
This pre-populate the phone field corretly using this code:
<%= simple_form_for #survey, :html => { :class => 'form-horizontal' } do |f| %>
<%= f.input :state, :required => true %>
<%= f.input :zip, :required => true %>
<%= f.input :phone, :required => true, :input_html => { :value => params['phone'] } %>
<% end %>
The problem is if the form is submitted without a required field
the form is reloaded but the phone input value is not retained.
If the form is submitted without a value for zip
the reloaded page with validation errors in red URL is now:
http://localhost:3000/surveys
If, say, the state field is correct but no zip code the form is reloaded
with an error msg saying zip is required.
The state value is retained however the phone is not.
I guess it has to do with :value => params['phone'] in the f.input for the phone.
Is there anyway I can populate the simple_form with URL paramenters
on it's initial load and have those value retained if the serverside validation fails?
Many thanks.
Remove the :value from your view:
<%= f.input :phone, :required => true %>
and use this URL:
http://localhost:3000/surveys/new?survey[phone]=8675309
That should generate the "standard" survey parameter hash expected by the controller. In my test, that works the same as if the user had typed in the value, with the usual validation handling.
Inside the controller, the hash is called params[survey] with individual parameters represented as params[survey][phone], params[survey][zip], etc.
With the help of this answer, I found that you can generate the URL with the link_to signature link_to(body, url_options = {}, html_options = {}):
<%= link_to 'New survey', { :controller => "surveys",
:action => "new",
:survey => { :phone => "8675309", :zip => "10001" } },
{ :target => "_blank" } %>
Note that url_options is the first hash, and within that hash you have a survey hash for pre-loading values. Finally comes the optional hash of html_options (where I added target="_blank" for illustration purposes).
Thanks Mark,
I re-posted this question again a while back and it was answered corretly here:
Rails simple_form server side validations lost URL params

Render #object and locals vs render :partial

I want to pass a local variable that contains the origin to come on a specific page, this variable contains just a symbol with the value.
When I use this code it works perfect, the origin variable is accessible in the partial :
render :partial => "products", :collection => #products, :locals => {:origin => :gallery}
But when I use this code, the origin is not set and not accessible in the partial :
render #products, :locals => {:origin => :gallery}
What is the difference here? Is the second line of code not render the partial like the first line?
<%= render #products %>
Is indeed the shorthand syntax for rendering a partial. But with the shorthand syntax, Rails will ignore the ":locals" variable. There's more on this in the Rails Guides.
So if you want to pass extra options to the render, you have to specify ":partial => ...". If you want to know why this happens, you can take a look at the Rails source.
There's a good explanation here: Rails: confused about syntax for passing locals to partials
The short version is that you can just omit :locals in the second example:
render #products, :origin => :gallery

Routing with id and handle in Rails

I'm trying to set up rails to use both the ID and the Handle (which is just an URL safe version of the title) of a blog post in the route.
match '/articles/:id/:handle', :to => 'articles#show'
resources :articles
This works, of course -- but I can't seem to set up the to_param method in the model os the longer URL -- with the handle attached, is the default.
This doesn't work (not that I really expected it to):
def to_param
"#{id}/#{handle}"
end
I get a No route matches {:action=>"edit", :controller=>"articles", error. I also tried just using the handle, but then Rails generates links to the resource just using the handle and not the ID. I know I can do it with a - in stead of a /, but I prefer the /. Any way to make this work? If I have to add some extra paremeters to my link_to helpers, that's okay.
Did you try to pass a Hash to link_to?
link_to "Link", {:id => #article.id, :handle => #article.handle}
Update
You have to modify your routes:
match '/articles/:id/:handle', :to => 'articles#show', :as => :article_with_handle
and use the following helper to generate the link:
link_to "Link", article_with_handle_path(:id => #article.id, :handle => #article.handle)
You can override the helper to simplify things:
def article_with_handle_path(article)
super(:id => article.id, :handle => article.handle)
end
and use it like this:
link_to "Link", article_with_handle_path(#article)
Okay, here's what I did to remove the query string problem from the answer above:
Changed the route to this:
match '/articles/:id/:handle' => 'articles#show', :as => :handle
Removed the to_param method from the model and then generated the link like this:
link_to 'Show', handle_path(:handle => article.handle, :id => article.id) %>
That works, but could be condensed, obviously, with the helper above. Just change the one line to: args[1] = handle_path(:id => args[1].id, :handle => args[1].handle)