Rails 3 - Using form Params in a controller's Update? - ruby-on-rails

I have the following form:
<%=form_for [:project, #permission], :url => { :action => "update" } do |f| %>
<% roles = Role.all %>
Role: <%= f.collection_select :role_id, roles, :id, :name, :prompt => true %>
<%=f.submit "Send Request" %>
<%=f.hidden_field :user_id %>
<% end %>
In my controller I have:
def update
#permission = Permission.find_by_user_id(params[:user_id])
.
.
.
end
** What I want to do is update the role_id,,,, so I need the above to find the permission record... Problem is,,, params[:user_id] is coming back null?
Am I missing something? thanks
Update
Here is the error and request params, which show the vars are there?
Started POST "/projects/3/permissions/useronproject" for 127.0.0.1 at Thu Oct 14 12:17:12 -0700 2010
Processing by PermissionsController#update as HTML
Parameters: {"commit"=>"Send Request", "authenticity_token"=>"KJ2C20MzTJ8VQV0NiNzOr357QKV5hWjeuazOBcS5iPU=", "utf8"=>"✓", "id"=>"useronproject", "permission"=>{"role_id"=>"1", "user_id"=>"11"}, "project_id"=>"3"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE ("users"."id" = 1) LIMIT 1
Permission Load (0.1ms) SELECT "permissions".* FROM "permissions" WHERE ("permissions"."user_id" IS NULL) LIMIT 1
see - user_id is NULL?

user_id is further down the params hash. Try:
params[:permission][:user_id]

Related

How to use a text_field to input a many_to_many association in rails?

I want to replace a select field with a text_field (to which I'm going to add autocomplete), so that all possible associations don't have to be loaded every time.
This is the form:
<%= form_for(Relation.new) do |f| %>
<%= f.hidden_field :dependency_id, :value => #article.id %>
<%= f.text_field :dependent_title %>
<%= f.submit %>
<% end %>
And this is the model:
def dependent_title
dependent.try(:title)
end
def dependent_title=(title)
self.dependent = Article.find_by_title(title) if title.present?
end
When I type in a title and press "submit" nothing happens.
It seems to work in the rails console:
irb(main):024:0> rel.dependent_title=("Optimization")
Article Load (1.0ms) SELECT "articles".* FROM "articles" WHERE "articles"."title" = ? LIMIT ? [["title", "Optimization"], ["LIMIT", 1]]
=> "Optimization"
irb(main):025:0> rel.dependent_title
=> "Optimization"
irb(main):026:0> rel.dependent_id
=> 479
I'm guessing you are looking for a field that looks like a text field but does the work of select field and with search option.
If I've understood your need correctly, you could research on select2 - a jQuery solution to your problem.
https://select2.org/
http://select2.github.io/select2/

If URL contains string?

How can I use a conditional to do one thing if :name is passed to the _form and another thing if that :name isn't passed?
With :name passed:
Started GET "/inspirations/new?inspiration%5Bname%5D=Always+trust+yourself+more+than+you+doubt+yourself" for 127.0.0.1 at 2016-11-08 01:00:44 -0500
Processing by InspirationsController#new as HTML
Parameters: {"inspiration"=>{"name"=>"Always trust yourself more than you doubt yourself"}}
Without :name passed:
Started GET "/inspirations/new" for 127.0.0.1 at 2016-11-08 01:16:18 -0500
Processing by InspirationsController#new as */*
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]]
Inspiration Load (0.4ms) SELECT "inspirations".* FROM "inspirations" WHERE "inspirations"."id" IS NULL LIMIT 1
Rendered inspirations/_form.html.erb (4.1ms)
Rendered inspirations/new.html.erb within layouts/modal (5.9ms)
Completed 200 OK in 49ms (Views: 41.9ms | ActiveRecord: 0.7ms)
_form
<%= simple_form_for(#inspiration) do |f| %>
<%= f.text_area :name %>
<% if params[:name].nil? %> # Should Be Triggered If No :name Is Present in URL
etc...
<% end %>
<% end %>
So for example when a URL includes a string:
http://www.livetochallenge.com/inspirations/new?inspiration%5Bname%5D=Life+would+be+easier+if+I+had+the+source+code.
But I often use a URL shortener.
Didn't work for me:
Is there a way to check if part of the URL contains a certain string
including url parameters in if statement
Try this:
<%= simple_form_for(#inspiration) do |f| %>
<%= f.text_area :name %>
<% if params[:inspiration].try(:[], :name).nil? %> # Should Be Triggered If No :name Is Present in URL
etc...
<% end %>
<% end %>
This will check :name inside params[:inspiration] only if the later is present. So, no error should occur.
You can avoid the error using fetch.
<%= simple_form_for(#inspiration) do |f| %>
<%= f.text_area :name %>
<%= f.text_area :name %>
<% name = params.fetch(:inspiration, {}).fetch(:name, nil) %>
<% if name.nil? %>
etc...
<% end %>
<% end %>

Saving multiple records with params.require in ruby

I'm trying to update multiple records. The form generates fine and submits fine and the data is sent. The records are looked up to update, but no data is ever saved. I have my controller logic, form logic and console dump below. I'm trying to duplicate what Anthony Lewis put together but I have a feeling I am not passing the right data into or defining correctly the params.require().permit() method. Thanks in advance for your help!
class ConfigController < ApplicationController
def edit
#services = Service.all
end
def update
params["service"].keys.each do |id|
#service = Service.find(id.to_i)
#service.update_attributes!(service_params)
end
redirect_to config_url
end
private
def service_params
params.require(:service).permit(:id, :client_id, :client_secret)
end
end
Form code is:
<%= form_for :service, :url => update_config_path, :html => { :class => "form-horizontal", :method => "put", :remote => true } do %>
<% #services.each do |s| %>
<%= fields_for "service[]", s do |service_field| %>
<fieldset>
<legend><%= s.name %></legend>
<div class="form-group">
<%= service_field.label :client_id, "Consumer Key", :class => "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= service_field.text_field :client_id, :class => "form-control" %>
</div>
</div>
<div class="form-group">
<%= service_field.label :client_secret, "Consumer Secret", :class => "col-sm-2 control-label" %>
<div class="col-sm-10">
<%= service_field.text_field :client_secret, :class => "form-control" %>
</div>
</div>
</fieldset>
<% end %>
<% end %>
<%= submit_tag %>
<% end %>
Console reads:
Started PUT "/config" for 127.0.0.1 at 2013-11-22 15:44:08 -0800
Processing by ConfigController#update as JS
Parameters: {"utf8"=>"✓", "service"=>{"1"=>{"client_id"=>"testid", "client_secret"=>"testsecret"}, "2"=>{"client_id"=>"testkey", "client_secret"=>""}, "3"=>{"client_id"=>"", "client_secret"=>""}}, "commit"=>"Save changes"}
Service Load (0.3ms) SELECT "services".* FROM "services" WHERE "services"."id" = $1 LIMIT 1 [["id", 1]]
Unpermitted parameters: 1, 2, 3
(0.1ms) BEGIN
(0.1ms) COMMIT
Unpermitted parameters: 1, 2, 3
{}
Service Load (0.2ms) SELECT "services".* FROM "services" WHERE "services"."id" = $1 LIMIT 1 [["id", 2]]
Unpermitted parameters: 1, 2, 3
(0.1ms) BEGIN
(0.1ms) COMMIT
Unpermitted parameters: 1, 2, 3
{}
Service Load (0.2ms) SELECT "services".* FROM "services" WHERE "services"."id" = $1 LIMIT 1 [["id", 3]]
Unpermitted parameters: 1, 2, 3
(0.1ms) BEGIN
(0.1ms) COMMIT
Unpermitted parameters: 1, 2, 3
{}
Redirected to http://localhost:3000/config
Completed 302 Found in 6ms (ActiveRecord: 1.1ms)
I found a solution, but perhaps it isn't the best. Let me know if someone has a better idea and I'd be happy to try it!
In the solution I updated my controllers update action and the service_params.
I passed id to service_params and called fetch method on the require method to get the correct params. I noticed that in the console it read Unpermitted parameters: 1, 2, 3 when it was saving each record indicating the params were an array and I also noticed in #Vijay's solution he tried to narrow down the params as well. After some Googling and console logging I came up with the code below.
def update
params["service"].keys.each do |id|
#service = Service.find(id.to_i)
#service.update_attributes!(service_params(id))
end
redirect_to config_url
end
def service_params(id)
params.require(:service).fetch(id).permit( :client_id, :client_secret )
end
What do you think?
Try this...
params.require(:service).permit( id: [ :client_id, :client_secret ] )
Your strong parameters line should be
params.require(:service).permit( [:id, :client_id, :client_secret ] )
This permits arrays of values
http://guides.rubyonrails.org/action_controller_overview.html#more-examples
Try this one and it will work.
Let me know if you get any issue
def service_params
params.require(:service).map do |_, p|
p.permit(:id, :client_id, :client_secret)
end
end
http://blog.sensible.io/2013/08/17/strong-parameters-by-example.html
Please try:
def update
Service.update(service_params.keys, service_params.values
end
def service_params
params.permit(service: [:client_id, :client_secret]).require(:service)
end

setting up search model to wrap around user model

I was finally able to come up with some sort of structure for my advanced search. The idea is to have a search that pulls data from the User model. So I built a search model which will be a kind of wrapper around the user model. For example: when I say Search.search_for(options), in the search_for method it will use the options to search on the User model and return the results, which you can display on the page. I came up with this method as I was told I have to duplicate the values, but I figured I just need to make Search call the underlying (already existing) User model.
So I have a view from where users can search. I have to collect all the options they have specified that they want to search on (gender, age, zip code, do they have kids, religion and ethnicity). Collect the options and submit the form to SearchController.
I have the concept down, but am struggling with the execution since I am new to Rails. The code below is essentially what I have (minus User model as it's filled with other parts from app). I'm not sure how to finish the rest of the coding to pull this off.
Searches_controller:
def new
#search = Search.new
end
def create
#search = Search.new(params[:search])
if #search.save
redirect_to #search
else
render 'new'
end
end
def show
#search = Search.find(params[:id])
#users = Users.search(params)
end
end
search model:
attr_accessible :age, :children, :ethnicity, :gender, :religion, :zip_code
def users
#users ||= find_users
end
def self.search(params)
end
private
def find_users
users = User.order(:id)
users = users.where(gender: gender) if gender
users = users.where(:ethnicity => ethnicity) if ethnicity
end
new.html (advanced search page):
<%= form_for #search do |f| %>
<div class="field">
<%= f.label :gender %><br />
<%= f.select :gender, ['man', 'woman'], :include_blank => true %>
</div>
<div class="field">
<%= f.label :zip_code %><br />
<%= f.text_field :zip_code %>
</div>
<div class="field">
<%= f.label :children %><br />
<%= f.select :children, ['Yes, they live with me', 'I want kids now', "I want one someday", "Not for me"], :include_blank => true %>
</div>
<div class="field">
<%= f.label :religion %><br />
<%= f.select :religion, ["Agnostic", "Atheist", "Christian", "Catholic", "Buddhist", "Hindu", "Jewish", "Muslim", "Spiritual without affiliation", "Other", "None", "Prefer not to say"], :include_blank => true %>
</div>
<div class="field">
<%= f.label :ethnicity %><br />
<%= f.select :ethnicity, ["Asian", "Biracial", "Indian", "Hispanic/Latin", "Middle Eastern", "Native American", "Pacific Islander", "White", "Other"], :include_blank => true %>
</div>
<div class="actions"><%= f.submit "Search" %></div>
<% end %>
show.html (view to show results):
<%= render #search.users %>
development log:
Started POST "/searches" for 127.0.0.1 at 2013-05-06 14:00:54 -0400
Processing by SearchesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Pher65dG6gRU9NGgv2q1ot0cfjq+MELgXE6dOtvcrY0=", "search"=>{"gender"=>"", "zip_code"=>"", "children"=>"", "religion"=>"", "ethnicity"=>"Asian"}, "commit"=>"Search"}
[1m[36m (0.2ms)[0m [1mBEGIN[0m
[1m[35mSQL (107.5ms)[0m INSERT INTO `searches` (`age`, `children`, `created_at`, `ethnicity`, `gender`, `religion`, `updated_at`, `zip_code`) VALUES (NULL, NULL, '2013-05-06 18:00:54', 0, NULL, NULL, '2013-05-06 18:00:54', '')
[1m[36m (60.1ms)[0m [1mCOMMIT[0m
Redirected to http://localhost:3000/searches/25
Completed 302 Found in 276ms (ActiveRecord: 167.7ms)
Started GET "/searches/25" for 127.0.0.1 at 2013-05-06 14:00:54 -0400
Processing by SearchesController#show as HTML
Parameters: {"id"=>"25"}
[1m[35mSearch Load (0.5ms)[0m SELECT `searches`.* FROM `searches` WHERE `searches`.`id` = 25 LIMIT 1
[1m[36mUser Load (73.2ms)[0m [1mSELECT `users`.* FROM `users` WHERE `users`.`zip_code` = '' AND `users`.`ethnicity` = '0' ORDER BY id[0m
Rendered collection (0.0ms)
Rendered searches/show.html.erb within layouts/application (81.4ms)
[1m[35mUser Load (0.6ms)[0m SELECT `users`.* FROM `users` WHERE `users`.`auth_token` = 'LTzif2q6921TM4pQzfmEGg' LIMIT 1
Completed 200 OK in 309ms (Views: 224.6ms | ActiveRecord: 74.3ms)
Ok, first of all make sure that the User model and the Search model have exactly the same attributes, so gender, zip_code, children, religion and ethnicity.
The only time you would need to have differing column names is if you want to do something a bit more "complex", such as searching a range, for example if the users table has age, then the searches table might have min_age and max_age.
Searches controller:
def new
#search = Search.new
end
def create
#search = Search.new(params[:search])
if #search.save
redirect_to #search
else
render 'new'
end
end
def show
#search = Search.find(params[:id])
#users = #search.users
end
Searches model:
def users
users = User.order(:id)
users = users.where(gender: gender) if gender
users = users.where(zip_code: zip_code) if zip_code
users = users.where(children: children) if children
users = users.where(religion: religion) if religion
users = users.where(ethnicity: ethnicity) if ethnicity
users
end
In app/views/searches/show.html.erb:
<h1>Search results</h1>
<%= render #users %>
And make sure that you have the partial app/views/users/_user.html.erb with something like:
<p><%= user.name %> - <%= user.email %></p> # or whatever
Now go to the search form and create a new search object, get the ID from the URL (lets say it's 34).
Then go into rails console and do:
#search = Search.find(34)
# should return something like: gender: "male", zip_code: nil, children: "Yes"..
# then try the users method:
#search.users
Not sure why your view isn't working. Make sure you have #users = #search.users in your searches controller under the show action, then go to views/searches/show.html.erb and do:
<% #users.each do |user| %>
<p><%= user.name %></p>
<% end %>
And see if that works.

Rails 3 Ajax file upload unsuccessful with remotipart gem

I am having trouble with Ajax file uploading in Rails 3.0.5 Ruby v 1.8.7 using the gem 'remotipart', '~> 0.4'. I have success with the alerts showing up when I remove the if #asset.save? statement in the controller but when its there the js file isn't called. For some reason the assets are not being saved.
Any ideas?
Controller:
def create
#asset = Asset.new(params[:asset])
respond_to do |format|
if #asset.save
format.html
format.js
end
end
end
View:
<%= form_for #asset, :remote => true, :html => {:multipart => true}, :id => "new_asset_form" do |f| %>
<%= render :partial => 'shared/error_messages', :locals => { :target => #asset } %>
<%= f.hidden_field :company_id, :value => current_company.id %>
<%= f.file_field :asset %>
<%= submit_tag 'Add', :class => 'submit' %>
<% end %>
Create.js.erb:
<%= remotipart_response do %>
// Display a Javascript alert
alert('success!');
<% if remotipart_submitted? %>
alert('submitted via remotipart')
<% else %>
alert('submitted via native jquery-ujs')
<% end %>
<% end %>
Terminal Log:
Started POST "/assets" for 127.0.0.1 at Thu May 10 14:45:40 -0400 2012
Processing by AssetsController#create as JS
Parameters: {"commit"=>"Add", "authenticity_token"=>"9TDxFQfTGrdz8gKti413FoIr1JUSwLGQQXv/tJQd+sY=", "utf8"=>"✓", "_"=>"", "asset"=>{"company_id"=>"5"}}
Company Load (0.5ms) SELECT `companies`.* FROM `companies` WHERE `companies`.`subdomain` = 'demo' LIMIT 1
User Load (0.7ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 295 AND (company_id = 5) LIMIT 1
CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 295 AND (company_id = 5) LIMIT 1
Rendered assets/create.js.erb (0.7ms)
Completed 200 OK in 182ms (Views: 8.9ms | ActiveRecord: 1.2ms)
Thanks for any help. Been stuck for hours.
Try upgrading to the latest version of Remotipart, found here: http://os.alfajango.com/remotipart/

Resources