Database querying through Http in rails? - ruby-on-rails

I am working on rails app , In which I have created a table Product Name:string and Number: integer.
The application should give user a form where he can search a product by his number if product exists it should give product name from database.
My search.html.erb is this.
<%= form_for #products, :url => { :action => "create" }, :html => {:class => "nifty_form"} do |f| %>
<%= f.text_area :number, :size => "60x12" %>
<%= f.submit "Search" %>
<% end
What will be the definition of search Method in ProductController and routes i need to add in routes.rb?

Irrespective of nifty forms, this is how I would have done this:
In config/routes.rb
replace resources :products' with
resources :products do
post 'search', :on => :collection
end
This will give me a search_products_path
In your view:
<%= form_for(:search, :url => search_products_path) do |f| %>
<%= f.text_field :number, :placeholder => "Enter number to search" %>
<%= f.submit "Search" %>
<% end %>
In your products_controller.rb
def search
number = params[:search][:number]
#result = Product.find_by_number(number)
#not_found = true unless #result
end
In your views/products/search.html.erb, use #result to show the product information; take care while checking whether or not the desired product is actually found or not. I have set the boolean #not_found in case it doesn't exist.

Related

Ruby on rails changes not reflecting after editing user's details

I am Rails newbie. I am creating a section that is pulling existing user's details and when the user click on edit, he can save the changes he has made. However, the changes aren't reflecting once the user saves it. Can you tell me what I am missing in here?
Here's the html/ruby form I am using:
<%= form_tag(html: {:id => 'user_profile_form'}, :url => patient_profile_path(#user), :method => :put) do %>
<%= text_field_tag(:inputFieldName, "#{#user.first_name} #{#user.last_name}", {:disabled => true}) %>
<%= submit_tag 'Save', :id=> 'saveButton' %>
<%= end %>
Here's the routes:
put :patient_profile, to: 'users#patient_profile'
post :dashboard, to: 'dashboard#index'
Here are the controller codes:
def patient_profile
if params[:user]
u = params[:user]
#user.first_name = u[:first_name] unless u[:first_name].nil? || u[:first_name].empty?
#user.last_name = u[:last_name] unless u[:last_name].nil? || u[:last_name].empty?
#user.save!
# index
render :index
end
end
It doesn't look like your form is actually updating anything since your form fields don't match your model. Try simplifying your form action:
View
<%= form_for(#user, html: {:id => 'user_profile_form'}, :url => patient_profile_path(#user), :method => :put) do |f| %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<%= f.submit "Update User" %>
<%= end %>
Controller:
def patient_profile
# TODO: Handle failed validation
#user.update_attributes!(params[:user])
# index
render :index
end
end
def user_params
params.require(:user).permit(:first_name, :last_name)
end

Rails: Unknown action The action 'update' could not be found for OtherController

I began learning rails several days before. Here I have a project setup. I generate a new controller named "my", the method in it is called "update".
The controller is like:
class MyController < ApplicationController
def update
#person = Entry.last
#fname = #person.first_name
#lname = #person.last_name
#person.update_attributes({:address => params[:st_name],
:salary => params[:salary], :loan => params[:loan],
:loan_reason => params[:reason]})
if !#person.address.nil? then render "show" end
end
end
In my form of the HTML, codes are:
<%= form_tag**({:controller => "my", :action => "update"} , :method => 'get')** do %>
<p> Address: <%= text_field_tag 'st_name', #address %>
<p> Salary:
<%= text_field_tag 'salary', #salary %>
<p> Loan Amount:
<%= text_field_tag 'loan', #loan %>
<p> Loan Reason:
<%= text_field_tag 'reason', #loan_reason %>
<%= submit_tag 'send' %>
<% end %>
Must have something wrong with the 1 line.
When I run the project, it says:
Unknown action
The action 'update' could not be found for OtherController
Can anyone give me some advece? Thanks...
should be :url => {:controller => "my", :action => "update"}

Ruby on Rails custom update action

I want to update member_id, which triggers update of :location_stock.
I have got these custom actions in
costumes_and_cost_records_controller.rb:
def rent
#costumes_and_cost_record = CostumesAndCostRecord.find(params[:costumes_and_cost_record_id])
end
def rent_method
#costumes_and_cost_record = CostumesAndCostRecord.find(params[:costumes_and_cost_record_id])
#costumes_and_cost_record.update_attributes(:member_id => params.permit(:member_id), :location_stock => true)
redirect_to #costumes_and_cost_record
end
I used simple form in view rent.html.erb:
<%= simple_form_for #costumes_and_cost_record do |f| %>
<%= f.association :member, :label => "Member", label_method: :to_s, value_method: :member_id, include_blank: true %>
<%= f.submit "Rent", :controller => :costumes_and_cost_records, :action => :rent_method, :method => :put, :member_id => :member %> <%# updates only member_id, doesnt update :location_stock %>
<%# link_to "Rent", :controller => :costumes_and_cost_records, :action => :rent_method, :method => :put, :member_id => :member_id %> <%# updates :location_stock, sets member_id = NULL %>
<% end %>
Now if I use submit button :member_id updates but controller doesn't update :location_stock.
If I use link_to :location_stock updates, but :member_id is set to NULL.
I want to update both attributes. Should I use submit button or link_to and how to fix this issue?
I set routes.rb to make both link_to and submit methods in view work:
resources :costumes_and_cost_records do
post 'show'
get 'rent'
get 'rent_method'
end
Any help is greatly appreciated.
If I understand you correctly you need to call rent_method to update member_id
Routes changes
put 'rent_method'
View changes
<%= simple_form_for #costumes_and_cost_record, method: :put, url: [#costumes_and_cost_record, :rent_method] do |f| %>
<%= f.association :member, :label => "Member", label_method: :to_s, value_method: :member_id, include_blank: true %>
<%= f.submit "Rent" %>
<% end %>
Controller
def rent_method
#costumes_and_cost_record = CostumesAndCostRecord.find(params[:costumes_and_cost_record_id])
#costumes_and_cost_record.update_attributes(:member_id => member_params[:member_id], :location_stock => true)
redirect_to #costumes_and_cost_record
end
def member_params
params.require(:costumes_and_cost_record).permit(:member_id)
end
Routes
Firstly, if you want to have member_id present, you'll probably be best using nested routes as follows:
#config/routes.rb
resources :member do.
resources :costumes_and_cost_records do
... #-> domain.com/members/2/costumes_and_cost_records/
end
end
This will give you the value required for params[:member_id] from your link:
<%= link_to "Member", member_costumes_and_cost_records_path(member_id) %>
Form
In your form, you then need to be able to define the url correctly (Rails naturally submits to the CRUD based actions, not custom ones):
<%= simple_form_for #costumes_and_cost_record, url: your_rent_method_path, method: :patch do |f| %>
This will submit to the rend_method path, or whichever custom action you wish to request.
--
I would personally keep any activity you have in the controller to a single action - this will allow you to keep all the business logic in one action, which is preferred for the MVC programming pattern
It took me 3 days but I finally fixed the problem. Ruslan Kyrychuk's answer was good, but the problem was that I didn't follow Rails naming conventions. I had foreign key: costumes_and_cost_records.member_id and primary key:member.member_id so I renamed member.member_id to member.id and that fixed the problem.

Issue passing model instance to update action

In my Rails app I'm trying to create a form for updating model instance attributes with new info and am running into trouble.
When I hit submit on the edit form, the following error is thrown:
param is missing or the value is empty: product
And here's the code snippet it provides:
# all the attributes that must be submitted for the product to be listed
def product_params
params.require(:product).permit(:name, :price, :description)
end
end
I think the problem is that the model :product isn't getting passed from the edit form to the update action. Here's the form:
<h1>Edit your listing</h1>
<%= form_for edit_item_path(#product), url: {action: "update"} do |f| %>
<div><%= f.label :name %><br />
<%= f.text_field :name, :placeholder => "Name yourself" %>
</div>
<div><%= f.label :price %><br />
<%= f.number_field :price, :placeholder => "Name your price" %>
</div><br />
<div><%= f.label :description %><br />
<%= f.text_area :description, :cols => "50", :rows => "10", :placeholder => "Write a few sentences about the item you're listing. Is it in good condition? Are there any accessories included?"%>
</div>
<br />
<%= f.submit "Update listing" %>
<% end %>
Here are the edit and update actions in my products_controller:
def edit
#product = Product.find(params[:id])
end
def update
#product = Product.find(params[:id])
respond_to do |format|
if #product.update_attributes(product_params)
format.html {render :action => "show"}
else
format.html {render :action => "edit"}
end
end
end
Finally, my product routes
get "/products/new(.:format)" => "products#new", :as => "list_item"
post "/products/create(.:format)" => "products#create"
get "/products(.:format)" => "products#index"
get "/products/:id(.:format)" => "products#show"
get "/products/:id/edit(.:format)" => "products#edit", :as => "edit_item"
post "/products/:id/update(.:format)" => "products#update"
So anyone know what the problem is? Am I not passing the right info to the update action? If I'm not, what do I need to do to do it?
form_for
The problem you have is you're using form_for without any object
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, et
form_for helpers are primarily designed to give you a way to manage ActiveRecord objects:
<%= form_for #object do |f| %>
...
<% end %>
--
Fix
Everything inside this form block will have to work with the object in the form_for. As you have only used a path helper in your form_for method, it's not going to work as you hope.
You'll need to do this:
<%= form_for #product, url: {action: "update"} do |f| %>
This will ensure your form_for populates the object correctly. The error you have basically says your strong_params method is expecting this structure:
params => {
"product" => {
"name" => ____,
"price" => _____,
"description" => ______
}
}
As you've not included the #product object in your form_for, your params hash won't have the product key, thus causing your error. The fix is to populate the form_for element correctly
Replace
form_for edit_item_path(#product), url: {action: "update"}
with
form_for #product
which is similar to
form_for #product, as: :product, url: product_path(#product), method: :patch do |f|

Using rails form_for to retrieve records not create them

I have bike model:
class Bike < ActiveRecord::Base
has_one :make
has_one :model
has_one :year
I am trying to implement a form on my app's home page that has three collection_select inputs (the second two are dynamically populated based on the prior collection_select's selected value using AJAX) for make, model, and year. The form itself renders and all AJAX requests are working.
Upon submit, I would like to render the existing Bike model record's show page that matches the user's selection (based on the id's of the selected values in the collection_selects).
Here is the form (this is on the homepage and not the Bike's new page). I have created a search action in the bike controller but do not know how to pass any data to it:
<%= form_for(:bike, :url => {:controller => 'bikes', :action => 'search'}, :html => {:role => "form", :class => "form-horizontal"}) do |f| %>
<div class="form-group">
<%= label :make_id, 'Make' %>
<%= collection_select(:bike, :make_id, Make.all, :id, :name, {include_blank: true}, {:class=>'form-control'})%>
</div>
<div class="form-group">
<div id="bikeModels"
<p><%= render 'shared/model_questions_fields', :current_models => [] %></p>
</div>
</div>
<div class="form-group">
<div id="modelYears"
<p><%= render 'shared/year_questions_fields', :current_years => [] %></p>
</div>
</div>
<%= f.submit "Show Quote", class: "btn btn-primary btn-lg" %>
<% end %>
shared/model_questions_fields
<script type="text/javascript">
jQuery(function($) {
// when the #model field changes
$("#bike_model_id").change(function() {
// make a POST call and replace the content
var model = $('select#bike_model_id :selected').val();
if(model == "") model="0";
jQuery.get('/bikes/update_year_select/' + model, function(data){
$("#modelYears").html(data);
})
return false;
});
})
</script>
<%= label :model_id, 'Model' %>
<% if !current_models.blank? %>
<%= collection_select :bike, :model_id, current_models, :id , :name, {include_blank: true}, {:class=>'form-control'} %>
<% else %>
<%= collection_select :bike, :model_id, [], :id , :name, {include_blank: true}, {:class=>'form-control'} %>
<% end %>
shared/year_questions_fields
<%= label :year_id, 'Year' %>
<% if !current_years.blank? %>
<%= collection_select :bike, :year_id, current_years, :id , :year_value, {include_blank: true}, {:class=>'form-control'} %>
<% else %>
<%= collection_select :bike, :year_id, [], :id , :year_value, {include_blank: true}, {:class=>'form-control'} %>
<% end %>
bikes_controller
class BikesController < ApplicationController
before_action :set_bike, only: [:show, :edit, :update, :destroy]
# GET /bikes
# GET /bikes.json
def index
#bikes = Bike.paginate(page: params[:page])
end
# GET /bikes/1
# GET /bikes/1.json
def show
end
# GET /bikes/new
def new
#bike = Bike.new
end
def search
#bike = Bike.find_by(:make_id => make_id, :model_id => model_id, :year_id => year_id)
redirect_to :action => "show", :id => #bike.bike_id
end
def update_model_select
models = Model.where(:make_id=>params[:id]).order(:name) unless params[:id].blank?
render :partial => "shared/model_questions_fields", :locals => { :current_models => models }
end
def update_year_select
model = Model.find(params[:id])
render :partial => "shared/year_questions_fields", :locals => { :current_years => model.years }
end
private
# Use callbacks to share common setup or constraints between actions.
def set_bike
#bike = Bike.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def bike_params
params.require(:bike).permit(:year_id, :make, :make_id, :model, :model_id, :kind,
:msrp, :current_price, :customer_id, :side_picture, :like_new_value, :excellent_value, :good_value,
:fair_value)
end
end
I need to get the bike_id based on the make_id, model_id, and year the user selects. I am confused on how to get the record via the controller.
Not sure if this is the most efficient or best way, but I was able to solve this with the following code:
bikes_controller
def search
puts params[:bike][:make_id]
bike = Bike.find_by(:make_id => params[:bike][:make_id], :model_id => params[:bike][:model_id], :year_id => params[:bike][:year_value])
redirect_to :action => "show", :id => bike.id
end
I was incorrectly accessing the parameters (they were nested).

Resources