Custom name for params hash from Rails form_for - ruby-on-rails

Ordinarily, using form_for(#foo) means that on the back end of the form's action, you'll have the form data in params[:foo], but in my case I'd like to have a custom namespace applied to these params, i.e. params[:bar], not params[:foo].
I'm not talking about making the namespace longer by supplying the :namespace argument to the form_for method. To the contrary, my current name is overlong, and I want to shorten it. More importantly, I'm actually swapping a new model in place of an existing one, so the controller is filled with calls to params[:quoter], whereas our new model supplies params[:company_quoter_intf_quoter]. Any ideas?
Specs: Ruby 1.9.3, Rails 3.2.3

What you are looking for is:
form_for(#foo, :as => :bar)
The documentation for this can be found at:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html

Related

ruby on rails 4.2 - ActionController::UrlGenerationError in Prodotti#new

I'm following the tutorial http://guides.rubyonrails.org/getting_started.html but i'm stuck on section 5.2 'the first form'
The error is after i put prodotti_path
<%= form_for :prodotto, url: prodotti_path do |f| %>
my rake routes:
Prefix Verb URI Pattern Controller#Action
welcome_index GET /welcome/index(.:format) welcome#index
prodotti_index GET /prodotti(.:format) prodotti#index
POST /prodotti(.:format) prodotti#create
new_prodotti GET /prodotti/new(.:format) prodotti#new
edit_prodotti GET /prodotti/:id/edit(.:format) prodotti#edit
prodotti GET /prodotti/:id(.:format) prodotti#show
PATCH /prodotti/:id(.:format) prodotti#update
PUT /prodotti/:id(.:format) prodotti#update
DELETE /prodotti/:id(.:format) prodotti#destroy
root GET / welcome#index
but when i refresh the page http://localhost:3000/prodotti/new/ the rails say:
ActionController::UrlGenerationError in Prodotti#new
Why? i'm new to ruby and ror, sorry !
Firstly, welcome to the Rails community!
Here's what you need to do:
#app/controllers/prodottis_controller.rb
class ProdottisController < ApplicationController
def new
#prodotti = Prodotti.new
end
def create
#prodotti = Prodotti.new prodotti_params
end
private
def prodotti_params
params.require(:prodotti).permit(:x, :y, :z)
end
end
Then in your view:
#app/views/prodotti/new.html.erb
<%= form_for #prodotti do |f| %>
<%= f.text_field :attribute_name %>
<%= f.submit %>
<% end %>
OOP
The problem you have is you're using a symbol in your form_for. Whilst this does work, it is not the best way to get it working, especially for a beginner.
Without going into too much detail, I'll explain that form_for is what's known as a helper method. If you pass this certain credentials, it will construct an HTML form for you:
Typically, a form designed to create or update a resource reflects the
identity of the resource in several ways: (i) the url that the form is
sent to (the form element's action attribute) should result in a
request being routed to the appropriate controller action (with the
appropriate :id parameter in the case of an existing resource), (ii)
input fields should be named in such a way that in the controller
their values appear in the appropriate places within the params hash,
and (iii) for an existing record, when the form is initially
displayed, input fields corresponding to attributes of the resource
should show the current values of those attributes.
In Rails, this is usually achieved by creating the form using form_for
and a number of related helper methods. form_for generates an
appropriate form tag and yields a form builder object that knows the
model the form is about. Input fields are created by calling methods
defined on the form builder, which means they are able to generate the
appropriate names and default values corresponding to the model
attributes, as well as convenient IDs, etc.
This basically means that you're meant to pass objects to the form_for helper - objects which have been built in your model and assigned in your controller.
The objects in Ruby are used by Rails throughout your application. Indeed, as Ruby is object orientated, all the things you do with the language, and frameworks, are meant to revolve around objects too.
Rails is object orientated in its own way. Remember, Rails is a framework which sits on top of Ruby. Thus, anything you do has to have objects at the center of the flow:
Models construct the objects in Rails.
Everything from your routes to controller actions take the idea that your models will be invoking data objects -- making it that each "helper" method in Rails (such as form_for) can be used with the corresponding objects you've built.
This is why I recommended setting the appropriate variable and passing it to your form helper. This will tie into your routes and controller actions, and should work for you.

Affecting resulting params set from form_for

Relative newbie here to Ruby on Rails.
Using the standard form_for method in the view for my SomeobjController#new action
= form_for #someobj do |f|
.
.
.
%p.submits
= f.submit "Submit", :class => "submit"
a submission param[] array is produced that contains a hash of #someobj for all the fields set in the form, such that
param[someobj] => { "field1" => "val1", "field2" => "val2", ... }
I would prefer to put a different value, the result of someobj.to_s to param[someobj] for the SomeobjController#create to work with, such that
param[someobj] => "strvalfromtos"
I doubt it's relative, but just in case, the model underlying this #new action is not persistent in the database (i.e., Someobj is not derived from ActiveRecord::Base, though some portions of ActiveModel are included.)
I haven't had luck trying to adjust this until after #create is invoked, but its the submission from #new to #create that I want to amend. It's not clear to me if I should be focusing more on the form_for statement or doing something special in the controller (I'm guessing the form_for is the right focus).
And, yes, this whole thing is probably a bit OCD of me, but the actual fieldnames are long (appropriately for the model) but data needed by #create is very small.
Is there a relatively painless way to do this, assuming that someobj.to_s has already been written?
Many thanks,
Richard
Change
When you submit the form, your controller will receive the params hash, as you've stated (Rails params explained?)
That means you can change any value in the hash that you wish:
def create
#has access to the params hash
params[:owner][:key] = value
end
As the create method receives the hash object, you'll have to change it in here. But because it's a standard hash (which has already been declared), you should be able to alter it as required
Add
If you want to add values to the params hash, you can use the .merge method, like this:
def create
#has access to the params hash
params[:key].merge(user_id: current_user.id)
end

Rails form parameters: params[:controller][:variable] or params[:variable]?

In a Rails controller receiving a form POST, is it better to refer to parameters as params[:controller][:variable] or simply params[:variable]?
Rails' form helpers appears to name some fields as controller[variable] in the view, but the the controller somehow knows how to find the value when the controller uses params[:variable]. In other cases, it doesn't seem to know, particularly when I use a different controller name (e.g. form_for(#model, :as => :othercontroller, :url => :othercontroller_path(#model)).
The Rails documentation indicates that params[:variable] is sufficient, but this doesn't seem to be the case?

Type Error in RSpec controller spec

I am having troubles with an RSPec test. The test does a PUT with some objects in the request. The controller which receives the PUT seems to be not getting the correct values
For example, 'put :update, :id => #channel.id, :channel => #channel, :tags => #tag' Then, in the Controller, when I try to use params[:tags] there is an integer in that location. A Gist with the Spec and the controller method is at https://gist.github.com/3715021
This started happening when I upgraded from Rails 3.0.13 to 3.1.8
Any idea what might be happening here and how to resolve it?
I'm assuming that #tag is an object from your Tags model. When you give Rails an object like
`get :action, :foo => foo`
or in a url helper (e.g., foo_path(foo)),
Rails will turn your object into a parameter suitable for use in a url via the #to_param method. You're probably getting an integer because Tag#to_param returns the id of the tag in your db.
It looks like your update action, by contrast, expects params[:tags] to be a hash, presumably generated from a form that includes fields for values like tags[:name].
I can't help much more without knowing more about the relevant code. But I'm guessing what you want to do is change your test to read
put :update, :id => #channel.id, :channel => #channel, :tags => { :name => 'tag' }
or something like that, mimicking the params you'd get by actually submitting the form that PUTs to your update action.
This is difficult to help you because we don't know what you're trying to do. For example, it would be helpful if you showed more of the test (for example, the values you set as your variables) and the specific results of the test.
Anyway, is the #tags variable an arel object? and if so, are you expecting the ID as the value to be passed? If not, then you probably want to specify the attribute referenced in #tags. For example, #tags.name... Or, does #tags reference a hash, itself?

How Do I Pass A Parameter From link_to To A Controller?

Building a project with Rails 3.1
I would like to provide a link in a parent model's show page that passes the parent model's id to a child object controller's create method.
I'm guessing this will require a custom route, but have no idea how to build it.
Is this possible? Or would I be breaking a Rails convention? I don't want to use a multiple model form if I can avoid it.
Thanks!
You can just pass them in as arbitrary values:
link_to my_path(:extra_attribute => value, :foo => 'bar')

Resources