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.
Related
So my reconciliation model looks like this:
class Reconciliation < ApplicationRecord
belongs_to :location
belongs_to :company
has_and_belongs_to_many :inventory_items
accepts_nested_attributes_for :inventory_items, allow_destroy: true
end
My InventoryItem model looks like this:
class InventoryItem < ApplicationRecord
belongs_to :product
belongs_to :location, inverse_of: :inventory_items
has_and_belongs_to_many :reconciliations
end
In my ReconciliationsController, this is what my reconciliation_params looks like:
def new
#location = Location.find(params[:location_id])
#reconciliation = #location.reconciliations.new
#inventory_items = #location.inventory_items
#start_index = 0
#next_index = #start_index + 1
end
def reconciliation_params
params.require(:reconciliation).permit(:inventory_item_id, :location_id, :display_id, :inventory_items,
inventory_items_attributes: [:id, :quantity_left, :quantity_delivered, :_destroy]
)
end
This is the relevant section of my routes.rb:
resources :locations, shallow: true do
resources :inventory_items
resources :reconciliations
end
This is my views/reconciliations/_form.html.erb:
<%= simple_form_for #reconciliation, url: :location_reconciliations do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :location_id, as: :hidden %>
<%= f.simple_fields_for :inventory_item do |inventory| %>
<%= inventory.input :quantity_left %>
<%= inventory.input :quantity_delivered %>
<% end %>
</div>
<div class="form-actions">
<%= f.button :submit, "Update", class: "btn btn-primary" %>
</div>
<% end %>
This is my app/views/reconciliations/new.html.erb:
<% if params[:next].nil? %>
<%= render 'form', reconciliation: #reconciliation, inventory_item: #inventory_items[#start_index] %>
<% else %>
<%= render 'form', reconciliation: #reconciliation, inventory_item: #inventory_items[#next_index] %>
<% end %>
This is my log when I try to create a reconciliation object:
Started POST "/locations/2/reconciliations" for 127.0.0.1 at 2018-03-24 23:16:33 -0500
Processing by ReconciliationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"JZvhwloo0+XM9bmptxXGfnDw==", "reconciliation"=>{"location_id"=>"2", "inventory_item"=>{"quantity_left"=>"1", "quantity_delivered"=>"170"}}, "commit"=>"Update", "location_id"=>"2"}
Unpermitted parameter: :inventory_item
Location Load (0.9ms) SELECT "locations".* FROM "locations" WHERE "locations"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
(0.6ms) BEGIN
(0.7ms) ROLLBACK
Rendering reconciliations/new.html.erb within layouts/application
InventoryItem Load (1.0ms) SELECT "inventory_items".* FROM "inventory_items" WHERE "inventory_items"."location_id" = $1 [["location_id", 2]]
Product Load (1.0ms) SELECT "products".* FROM "products" WHERE "products"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
Rendered reconciliations/_form.html.erb (45.9ms)
Rendered reconciliations/new.html.erb within layouts/application (66.8ms)
Rendered shared/_navbar.html.erb (1.3ms)
Completed 200 OK in 202ms (Views: 115.1ms | ActiveRecord: 29.1ms)
I have tried simply adding :inventory_item to my params.require(:reconciliation).permit(..), but that doesn't work.
What am I missing?
Edit 1
When I checked the HTML for the inputs on my form, within the simple_fields_for, the HTML seems to be fine:
<input class="string required" type="text" name="reconciliation[inventory_item][quantity_left]" id="reconciliation_inventory_item_quantity_left">
Edit 2
When I change the simple_fields_for call to be plural, i.e. :inventory_items, rather than :inventory_item like this:
That entire portion of the form disappears altogether.
This is what the HTML looks like:
<div class="form-inputs">
<div class="input hidden reconciliation_location_id"><input class="hidden" type="hidden" value="2" name="reconciliation[location_id]" id="reconciliation_location_id"></div>
</div>
This is how the HTML looks when that simple_field_for :inventory_item is singular:
<div class="form-inputs">
<div class="input hidden reconciliation_location_id"><input class="hidden" type="hidden" value="2" name="reconciliation[location_id]" id="reconciliation_location_id"></div>
<div class="input string required reconciliation_inventory_item_quantity_left"><label class="string required" for="reconciliation_inventory_item_quantity_left"><abbr title="required">*</abbr> Quantity left</label><input class="string required" type="text" name="reconciliation[inventory_item][quantity_left]" id="reconciliation_inventory_item_quantity_left"></div>
<div class="input string required reconciliation_inventory_item_quantity_delivered"><label class="string required" for="reconciliation_inventory_item_quantity_delivered"><abbr title="required">*</abbr> Quantity delivered</label><input class="string required" type="text" name="reconciliation[inventory_item][quantity_delivered]" id="reconciliation_inventory_item_quantity_delivered"></div>
</div>
I have tried simply adding :inventory_item to my params.require(:reconciliation).permit(..), but that doesn't work.
If you want permit inventory_item, you must specify its structure, because it is not a simple field, but a hash:
def reconciliation_params
params.require(:reconciliation).permit(:location_id, :display_id, inventory_item: [:id, :quantity_left, :quantity_delivered] )
end
By looking at your log, you are not passing the inventory_item_id, which might be needed to update this specific item:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"JZvhwloo0+XM9bmptxXGfnDw==",
"reconciliation"=>{"location_id"=>"2", "inventory_item"=>
{"quantity_left"=>"1", "quantity_delivered"=>"170"}},
"commit"=>"Update", "location_id"=>"2"}
You could add it as a hidden field in the nested form.
Form of association should be plural f.simple_fields_for :inventory_items.
You should initialize a new inventory_item object in the new controller's action
def new
#reconciliation = Reconciliation.new
# you can create as many new items as you want
#reconciliation.inventory_items.build
end
If you want to dynamically add items to the form i advise you to use https://github.com/nathanvda/cocoon
BUT it looks like you want to add existing inventory_item to a new reconciliation, you better use has_many through assocations http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many
Its easier to add a join model objects with neccessary fields and associations.
Another advise: do not send local variable to partial if you are using instance variable in this partial
# render partial
render 'form', reconciliation: #reconciliation
# partial with form for local variable
simple_form_for reconciliation
and i think your form partial will not work for the edit action because of hardcoded url, you can pass url in a variable:
# new html
render 'form', reconciliation: #reconciliation, url_var: location_reconciliations(#location)
# edit
render 'form', reconciliation: #reconciliation, url_var: reconciliations(#reconciliation)
# form
simple_form_for reconciliation, url: url_var
I have a Category model and a Standard model. A category has many standards through a "join table" model CategoryStandard. In my view, I have a form where I can edit the category description, and then add or remove standards from that category. So, my nested attributes are for :category_standards, because I'm not editing the standard itself, just adding or removing relationships, if that makes sense.
Here's the important part of the view:
<%= form_for(#category) do |f| %>
...
<div class="field">
<%= f.label :description %>
<%= f.text_field :description %>
</div>
<%= label_tag nil, "Standards in this Category" %>
<div id="standard-list">
<%= f.fields_for :category_standards do |ff| %>
<div class="field">
<%= ff.object.standard.number_with_exceptions %>
<%= ff.hidden_field :standard_id %>
<%= ff.hidden_field :_destroy %>
<%= link_to "<span class='glyphicon glyphicon-remove'></span>".html_safe, "", class: "del-std-btn", title: "Remove standard from category" %>
</div>
<% end %>
<div class="hidden" id="std-add-new-template">
<div class="field">
<%= f.fields_for :category_standards, CategoryStandard.new, child_index: "new_id" do |ff| %>
<%= ff.collection_select :standard_id, #standards - #category.standards, :id, :number_with_exceptions, prompt: "Select a standard to add" %>
<% end %>
</div>
</div>
</div>
...
<% end %>
There's some jQuery under the hood to manipulate the "rows", but that works fine and I don't think it's part of my problem, so I'll omit it.
In my Category model, I have:
class Category < ActiveRecord::Base
has_many :category_standards, dependent: :destroy
has_many :standards, through: :category_standards
validates :description, presence: true,
uniqueness: true
accepts_nested_attributes_for :category_standards, allow_destroy: true, reject_if: proc { |attributes| attributes['standard_id'].blank?}
end
And in my Categories controller, I have:
def category_params
params.require(:category).permit(:description, category_standards_attributes: [:id, :standard_id, :_destroy])
end
But when I try to add a standard to a category, I get these lines in my server log (reformatted in the hopes of making it more readable):
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"***********",
"category"=>{
"description"=>"Drinking Water System Components",
"category_standards_attributes"=>{
"0"=>{
"standard_id"=>"2",
"_destroy"=>"false",
"id"=>"1"
},
"new_id"=>{
"standard_id"=>""
},
"1424899001814"=>{
"standard_id"=>"1"
}
}
},
"commit"=>"Save Changes",
"id"=>"2"
}
User Load (5.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Category Load (4.0ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = $1 LIMIT 1 [["id", "2"]]
Unpermitted parameters: 0, new_id, 1424899001814
(4.0ms) BEGIN
Category Exists (6.0ms) SELECT 1 AS one FROM "categories" WHERE ("categories"."description" = 'Drinking Water System Components' AND "categories"."id" != 2) LIMIT 1
SQL (6.0ms) UPDATE "categories" SET "description" = $1, "updated_at" = $2 WHERE "categories"."id" = 2 [["description", "Drinking Water System Components"], ["updated_at", Wed, 25 Feb 2015 21:16:44 UTC +00:00]]
It updates the description field just fine, but what's up with the Unpermitted parameters? My attributes hash comes out just like the example in the Rails Guide on nested forms, and it even says "The keys of the :addresses_attributes hash are unimportant, they need merely be different for each address." And yet it's the keys that are getting denied for me.
Where have I gone wrong? Thanks!
Figured it out, after a lot of reading. The missing piece was here.
Hashes with integer keys are treated differently and you can declare the attributes as if they were direct children. You get these kinds of parameters when you use accepts_nested_attributes_for in combination with a has_many association:
# To whitelist the following data:
# {"book" => {"title" => "Some Book",
# "chapters_attributes" => { "1" => {"title" => "First Chapter"},
# "2" => {"title" => "Second Chapter"}}}}
params.require(:book).permit(:title, chapters_attributes: [:title])
The important part of that was "Hashes with integer keys". My hash keys were passing as "0", "new_id", "1240934304343". It isn't important that I use "new_id", because that's just a placeholder value that gets changed in my jQuery when new rows are added. Only the template row retains that value, which is fine, because it gets filtered out by my reject_if clause.
But the fact that "new_id" isn't an integer apparently was the thing that was mucking it all up. So I changed it to "-1", which Rails accepts (even though it is still filtered out by reject_if, as it should be).
<div class="hidden" id="std-add-new-template">
<div class="field">
<%= f.fields_for :category_standards, CategoryStandard.new, child_index: "-1" do |ff| %>
<%= ff.collection_select :standard_id, #standards - #category.standards, :id, :number_with_exceptions, prompt: "Select a standard to add" %>
<% end %>
</div>
</div>
Your attribute keys don't seem to match what you are expecting in your strong parameters, "new_id" and "1424899001814" certainly will not be permitted.
"new_id"=>{
"standard_id"=>""
},
"1424899001814"=>{
"standard_id"=>"1"
}
I suspect the way you are constructing your form is invalid. Try breaking it down to the simplest working form.. like:
<div id="standard-list">
<%= link_to "<span class='glyphicon glyphicon-remove'></span>".html_safe, "", class: "del-std-btn", title: "Remove standard from category" %>
<div class="hidden" id="std-add-new-template">
<div class="field">
<%= f.fields_for :category_standards do |ff| %>
<%= ff.object.standard.number_with_exceptions %>
<%= ff.hidden_field :standard_id %>
<%= ff.hidden_field :_destroy %>
<%= ff.collection_select :standard_id, #standards - #category.standards, :id, :number_with_exceptions, prompt: "Select a standard to add" %>
<% end %>
</div>
</div>
</div>
The intention is to have only one nested form, and by stripping it down create only one nested hash.
"category_standards_attributes"=>{
"0"=>{
"standard_id"=>"2",
"_destroy"=>"false",
"id"=>"1"
}
}
What happens with this?
I'm new to Ruby, and I'm developing my own app in Nitrous.
When I complete a form on my new.html.erb, and hit save, the show view loads. The page renders with HTML headers as expected, but no data fields from my model. I have also tried the index view, but there is no data being saved, I think.
I have generated a model called income, and run rake db:migrate successfully, wiht the right tables set up. I'm stumped as to what the problem is.
Any ideas gratefully received.
This is my controller: incomes_controller.rb
class IncomesController < ApplicationController
def index
#incomes = Income.all
end
def new
#income = Income.new
end
def create
#income = Income.new(income_params)
if #income.save
redirect_to(:action => 'show', :id => #income.id)
end
end
def show
#income = Income.find(params[:id])
end
private
def income_params
params.require(:income).permit(:first_name, :last_name, :date_of_birth, :income1, :income2, :income3, :income4, :income5, :income6, :income7, :income8, :income9, :income10)
end
end
My form in new.html.erb, is:
<%= simple_form_for #income do |f| %>
<%= f.input :first_name, label: 'First Name' %>
<%= f.input :last_name, label: 'Last Name' %>
<%= f.input :date_of_birth, label: 'Date of Birth', hint: 'dd/mm/yyyy' %>
<p>Income: Salary or Wages</p>
<%= f.input :income1, label: 'Take home salary or Wage' %>
<%= f.input :income2, label: 'Partner\'s salary or wage' %>
<%= f.input :income3, label: 'Other income from salary or wages' %>
<p>Other Income</p>
<%= f.input :income4, label: 'Maintanence or child support' %>
<%= f.input :income5, label: 'Boarders or lodgers' %>
<%= f.input :income6, label: 'Non-dependent contributions' %>
<%= f.input :income7, label: 'Student loands or grants' %>
<%= f.input :income7, label: 'Other' %>
<p>Benefits </p>
<%= f.input :income8, label: 'Sample input' %>
<%= f.input :income9, label: 'Sample input' %>
<%= f.input :income10, label: 'More sample inputs' %>
<%= f.button :submit, "Save and Proceed" %>
<h3>You will have a chance to review your form before you submit it. Once you click Save, you can come back and complete the rest of the form at a later date</h3>
<% end %>
And my show.html.erb file is:
<p>
<strong>First name:</strong>
<%= #income.first_name %>
</p>
<p>
<strong>Last name:</strong>
<%= #income.last_name %>
</p>
<p>
<strong>Date of Birth:</strong>
<%= #income.date_of_birth %>
</p>
<p>
<strong>Take home salary or Wage:</strong>
<%= #income.income1 %>
</p>
My model income.rb is:
class Income < ActiveRecord::Base
attr_accessor :first_name, :last_name, :date_of_birth, :income1, :income2, :income3, :income4, :income5, :income6, :income7, :income8, :income9, :income10
end
Development log output....
Processing by IncomesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"D4F40TAMcVsb7RbdUZwxXfsgGn1u/iD7R+DWvAwrtJ1q83mgequQbkyKPaheFjsLSZHlMBpDy+H7Rm+HdVeTFw==", "income"=>{"first_name"=>"Barak", "last_name"=>"Obama", "date_of_birth"=>"02/07/1990", "income1"=>"12345", "income2"=>"12345", "income3"=>"", "income4"=>"", "income5"=>"", "income6"=>"", "income7"=>"", "income8"=>"", "income9"=>"", "income10"=>""}, "commit"=>"Save and Proceed"}
[1m[35m (0.1ms)[0m begin transaction
[1m[36mSQL (0.5ms)[0m [1mINSERT INTO "incomes" ("created_at", "updated_at") VALUES (?, ?)[0m [["created_at", "2015-02-19 17:39:54.471034"], ["updated_at", "2015-02-19 17:39:54.471034"]]
[1m[35m (32.8ms)[0m commit transaction
Redirected to http://o-bot-laboratory-190030.euw1.nitrousbox.com/incomes/42
Started GET "/incomes/42" for 88.215.13.57 at 2015-02-19 17:39:54 +0000
Processing by IncomesController#show as HTML
Parameters: {"id"=>"42"}
[1m[36mIncome Load (0.3ms)[0m [1mSELECT "incomes".* FROM "incomes" WHERE "incomes"."id" = ? LIMIT 1[0m [["id", 42]]
Rendered incomes/show.html.erb within layouts/application (0.8ms)
Completed 200 OK in 94ms (Views: 75.6ms | ActiveRecord: 0.3ms)
Routes as requested....
Rails.application.routes.draw do
resources :incomes
root 'incomes#new'
end
Thanks to #RailsOuter and #jyrkim for your help. I found that the problem was indeed with my model file, and migration file.
I needed to remove the line attr_accessor from my model. I have since discovered that I must have modified my migration file to add columns, instead of generating a new migration. Now I have generated the new migration with the data columns, my data is showing!
Thanks again, very appreciative of your input to help out a newbie!
I have a advanced search form and I wanted to know how can I save the user selections to the database. The current setup saves each search performed to the database, thus allowing me to have statistics of what users are searching for on the website.
The question I have is how can I save that users selections to their account so that it preloads when they return to the website, or they can create lists of saved search options. I have a social networking app so this would be helpful to the User so that they do not have to enter the age range, zip code, etc each time they visit the website.
I'm not sure how to do this.
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
Search model:
def users
#users ||= find_users
end
private
def find_users
users = User.order(:id)
users = users.where(gender: gender) if gender.present?
users = users.where(zip_code: zip_code) if zip_code.present?
users = users.where(children: children) if children.present?
users = users.where(religion: religion) if religion.present?
users = users.where(ethnicity: ethnicity) if ethnicity.present?
if min_age.present? && max_age.present?
min = [ min_age, max_age ].min
max = [ min_age, max_age ].max
min_date = Date.today - min.years
max_date = Date.today - max.years
users = users.where("birthday BETWEEN ? AND ?", max_date, min_date)
users
end
users
end
end
Search form:
<%= form_for #search do |f| %>
<div class="field">
<%= f.label :gender %><br />
<%= f.select :gender, ['male', 'female'], :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> <%= f.select :min_age, (18..75), :include_blank => true %>
to
<%= f.select :max_age, (18..75), :include_blank => true %>
<div class="actions"><%= f.submit "Search" %></div>
<% end %>
you can use json, marshal or any other serializers to serialize the search params as a string ,then store it into the cookie or database.
You could store the search settings in the session. The drawback is that when a client visits the site from a different computer or browser, there are no saved search settings, because the session id is stored in a cookie.
If you really want the settings persisted in the database, you could create a search_settings field on the User model and serialize the settings to this field. If you are using Postgresql you could use the array or hstore column type.
I am having difficulty translating the Headfirst into Rails book which is based on Rails 2 into Rails 4 which is set up on my machine.
The exercise is trying to retrieve a record from a database and then, once edited, update the table.
I have tried many different ways and my current configuration is as follows - this will present the record for editing but will not actually update the record! (Infuriating!)
NB - I am not using 'strong_parameters' nor 'protected_attributes' - I did try this but was getting stack to deep and other errors.
My ad model is also empty - I have removed the att_accessible entries that I tried with the protected attributes gem.
Here is my - ad controller entry:
def update
#ad = Ad.find(params[:id])
#ad.update_attributes(update_params[:id])
redirect_to "/ads/#{#ad.id}"
end
private
def update_params
params.permit(:name, :description, :price, :seller_id, :email, :ad, :img_url)
end
end
EDIT VIEW:
<h1>Editing <%= #ad.name %></h1>
<%= form_for(#ad,:url=>{:action=>'update'}) do |f| %>
<p><b>Name</b><br /><%= f.text_field :name %></p>
<p><b>Description</b><br /><%= f.text_area :description %></p>
<p><b>Price</b><br /><%= f.text_field :price %></p>
<p><b>Seller</b><br /><%= f.text_field :seller_id %></p>
<p><b>Email</b><br /><%= f.text_field :email %></p>
<p><b>Img Url</b><br /><%= f.text_field :img_url %></p>
<p><%= f.submit "update" %></p>
<% end %>
Log Entry on Update:
Started PATCH "/ads/1/update" for 127.0.0.1 at 2013-08-13 22:35:51 +0100
Processing by AdsController#update as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"O4cN72FXCCkfkL7M6bozodbB0Aqor
NctOOV5sfXdado=", "ad"=>{"name"=>"Typewriter", "description"=>"Old manual typewr
iter. Many years useful service. Works best with a bottle next to it.", "price"=
>"71.95", "seller_id"=>"54", "email"=>"dhammett#email.com1", "img_url"=>"http://
homepage.mac.com/david_griffiths/typewriter.png"}, "commit"=>"update", "id"=>"1"
}
←[1m←[35mAd Load (1.0ms)←[0m SELECT "ads".* FROM "ads" WHERE "ads"."id" = ? L
IMIT 1 [["id", "1"]]
Unpermitted parameters: utf8, _method, authenticity_token, ad, commit, id
←[1m←[36m (0.0ms)←[0m ←[1mbegin transaction←[0m
←[1m←[35m (0.0ms)←[0m commit transaction
Redirected to http://localhost:3000/ads/1
Completed 302 Found in 54ms (ActiveRecord: 1.0ms)