Rails: Gmaps4Rails & Geocoder - setup - ruby-on-rails

Trying to figure out how to display a map in my rails 4 app show page.
I have a model called addresses. This is the address.rb file:
class Address < ActiveRecord::Base
geocoded_by :full_address # can also be an IP address
before_save :capitalise_address
before_save :upcase_zip
# --------------- associations
belongs_to :addressable, :polymorphic => true
# --------------- scopes
# --------------- validations
validates_presence_of :unit, :street, :zip, :country
# --------------- class methods
def first_line
[unit, street].join(' ')
end
def middle_line
if self.building.present?
end
end
def last_line
[city, region, zip].join(' ')
end
def country_name
self.country = ISO3166::Country[country]
country.translations[I18n.locale.to_s] || country.name
end
def address_without_country
[self.first_line, middle_line, last_line].compact.join(" ")
end
def full_address
[self.first_line, middle_line, last_line, country_name.upcase].compact.join("\n")
end
# --------------- callbacks
# after_validation :geocode, if self.full_address.changed?
# --------------- instance methods
# --------------- private methods
protected
def upcase_zip
zip.upcase
end
def capitalise_address
["building", "street", "city", "region", "country" ].each do | name |
self.attributes[name] = self.attributes[name].capitalize
end
end
end
I have added geocoded, gmap4rails, underscore gems to my gem file.
In my addresses controller I have:
class AddressesController < ApplicationController
before_action :set_address, only: [:show, :edit, :update, :destroy]
respond_to :html, :xml, :json
def index
#addresses = Address.all
respond_with(#addresses)
end
def show
respond_with(#address)
end
def new
#address = Address.new
respond_with(#address)
end
def edit
end
def create
#address = Address.new(address_params)
#address.save
respond_with(#address)
end
def update
#address.update(address_params)
respond_with(#address)
end
def destroy
#address.destroy
respond_with(#address)
end
private
def set_address
#address = Address.find(params[:id])
end
def address_params
params[:address].permit(:unit, :building, :street, :city, :region, :zip, :country)
end
end
In my address show page I have:
<script src="//maps.google.com/maps/api/js?v=3.13&sensor=false&libraries=geometry" type="text/javascript"></script>
<script src="//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js" type="text/javascript"></script>
<div class="containerfluid">
<div class="row">
<div class="col-md-12">
<div style='width: 800px;'>
<div id="map" style='width: 800px; height: 400px;'>
</div>
</div>
<div class="addressbacking">
<%= #address.full_address %>
<div style='width: 800px;'>
<div id="one_marker" style='width: 800px; height: 400px; z-index:1'></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers(<%=raw #hash.to_json %>);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
});
</script>
I am trying to follow this set up tutorial, which suggests adding this to my controller:
def index
#users = User.all
#hash = Gmaps4rails.build_markers(#users) do |user, marker|
marker.lat user.latitude
marker.lng user.longitude
marker.title user.title
end
end
Which I do (although I don't know what it means or if its the cause of my problem), so that my index action in the controller is:
def index
#addresses = Address.all
respond_with(#addresses)
#hash = Gmaps4rails.build_markers(#users) do |user, marker|
marker.lat user.latitude
marker.lng user.longitude
marker.title user.title
end
end
I have a form partial in my views which has input elements for each of the strong params showing at the bottom of my controller.
When I try this, a map renders, but its not the address that i entered in my form.
How do I fix this? I don't have longitude and latitude attributes in my address table.

You geocoded class Address, so it has latitude and longitude method. Was User class geocoded too?
def index
#addresses = Address.all
#hash = Gmaps4rails.build_markers(#addresses) do |address, marker|
marker.lat address.latitude
marker.lng address.longitude
end
end
Be sure to add params to addresses:
class AddLatitudeAndLongitudeToAddress < ActiveRecord::Migration
def change
add_column :addresses, :latitude, :float
add_column :addresses, :longitude, :float
end
end

Let's check app/assets/javascripts/addresses.coffee
For example:
class RichMarkerBuilder extends Gmaps.Google.Builders.Marker
create_marker: ->
options = _.extend #marker_options(), #rich_marker_options()
#serviceObject = new RichMarker options
rich_marker_options: ->
marker = document.createElement("div")
marker.setAttribute 'class', 'marker_container'
marker.innerHTML = #args.marker
{ content: marker }
handler = Gmaps.build 'Google', { builders: { Marker: RichMarkerBuilder} }
handler.buildMap { provider: {}, internal: {id: 'map'} }, ->
markers = handler.addMarkers([
{"lat": 0, "lng": 0, 'marker': '<span>Here!</span>'}
])
handler.bounds.extendWith(markers)
handler.fitMapToBounds()
In your model add
geocoded_by :full_address
after_validation :geocode

Related

ruby on rails about form_for

Hi I want to create an ec site and try to make quantity system.
What I want to do: Adding a item in quantity of CreateBasketItems(2021_create_basket_items.rb)
Question: How can I write some code in item/show.html.erb which is part of form_with() in particular?
2021_create_basket_items.rb
class CreateBasketItems < ActiveRecord::Migration[5.2]
def change
create_table :basket_items do |t|
t.references :basket, index: true, null: false, foreign_key: true
t.references :item, index: true, null: false, foreign_key: true
t.integer :quantity, null: false, default: 1
t.timestamps
end
end
end
item/show.html.erb
The url: show.html.erb => item_controller.rb/create
<%= form_for url: item_add_to_baskets_path(#item,#basket_item), method: :post do |f| %>
  <%= f.select :quantity,[1,2,3], id: "country1", class: "frm-field required sect" %>
<%= f.submit "add to basket", class: "item_add" %>
<% end %>
just in case the error is.
ArgumentError (wrong number of arguments (given 1, expected 0)):
item_controller.rb
class ItemsController < ApplicationController
# before_action :authenticate_user!
def show
basket = current_user.prepare_basket
#item = Item.find(params[:id])
#basket_item = basket.basket_items(params[:quantity])
end
def index
# if(params[:category])
# #items = Item.where(category: params[:category]).paginate(page: params[:page])
# else
# #items = Item.paginate(page: params[:page])
# end
#items = (params[:category]) ? Item.where(category: params[:category]).paginate(page: params[:page]) :
Item.paginate(page: params[:page])
end
end
add_to_basket_controller.rb
class Items::AddToBasketsController < Items::ApplicationController
def create
basket = current_user.prepare_basket
#item = Item.find(params[:item_id])
#basket_item = basket.basket_items(params[:quantity])
basket.basket_items.create!(item_id: #item.id, quantity: #basket_item)
flash[:success] = "your item in basket"
redirect_to baskets_path
end
end
There are a couple of issues with the code.
basket.basket_items doesn't expect any arguments but you're passing one. In fact, you don't need that line of code at all. Remove it.
You're not passing the right quantity to the create! call.
basket.basket_items.create!(item_id: #item.id, quantity: params[:quantity])

Validation Error * Checkin time must be a valid current or future time - ruby on rails

I'm running into an issue with my rails build. I've created a hotel application and when trying to check out a room at any future time or date it gives me an error described in the picture below. I'm open to any feedback and your help is sincerely appreciated! I've attached a screenshot of the issue and all my code that I can think of that might be related.
PICTURE OF THE PROBLEM
reservation.rb
class Reservation < ActiveRecord::Base
belongs_to :user
belongs_to :room
attr_accessor :checkin_date, :checkin_time, :checkout_date, :checkout_time
validates_presence_of :checkin_date
validates_presence_of :checkin_time
validates_presence_of :checkout_date
validates_presence_of :checkout_time
validates_presence_of :number_of_rooms
validate :future_checkin_date
validate :future_checkin_time
validate :future_checkout_date
validate :future_checkout_time
validate :no_of_rooms_greater_then_0, if: lambda { number_of_rooms.present? }
def future_checkin_date
if checkin_date.present? && checkin_date.to_date < DateTime.now.to_date
errors.add(:checkin_date, 'must be a valid current or future date')
end
end
def future_checkin_time
if checkin_time.present? && checkin_time.to_time < Time.now
errors.add(:checkin_time, 'must be a valid current or future time')
end
end
def future_checkout_date
if checkin_date.present? && checkout_date.present? &&
checkout_date.to_date < checkin_date.to_date
errors.add(:checkout_date, 'must be a valid date after your check in ' \
'date')
end
end
def future_checkout_time
if checkin_datetime.present? && checkout_datetime.present? &&
checkout_datetime <= checkin_datetime
errors.add(:checkout_time, 'must be a valid time after your check in ' \
'time.')
end
end
def no_of_rooms_greater_then_0
errors.add(:number_of_rooms, 'must be 1 or more to make a reservation') if
number_of_rooms <= 0
end
def convert_to_datetime
if self.checkin_date.present? && self.checkin_time.present?
self.checkin_datetime = self.merge_datetime(
self.checkin_date,
self.checkin_time
)
end
if self.checkout_date.present? && self.checkout_time.present?
self.checkout_datetime = self.merge_datetime(
self.checkout_date,
self.checkout_time
)
end
end
def merge_datetime(date1, time1)
res_date = Date.parse(date1)
res_time = Time.parse(time1)
merged_datetime = DateTime.new(
res_date.year,
res_date.month,
res_date.day,
res_time.hour,
res_time.min,
res_time.sec
)
end
def room_name
room.room_type.name
end
def decrease_room_inventory
room.update(inventory: (room.inventory -= number_of_rooms))
end
def self.default_checkin_date
DateTime.now.strftime('%Y-%m-%d')
end
def self.default_checkin_time
(DateTime.now.midday + 3.hours).strftime('%H:%M')
end
def self.default_checkout_date
DateTime.now.tomorrow.strftime('%Y-%m-%d')
end
def self.default_checkout_time
(DateTime.tomorrow.midday).strftime('%H:%M')
end
def self.users_reservations(user)
where('user_id = ?', user)
end
def reservation_date(booking_datetime)
booking_datetime.strftime('%Y-%m-%d')
end
def reservation_time(booking_datetime)
booking_datetime.strftime('%H:%M')
end
def self.reservations_checkin_setter(reservations)
reservations.each do |reservation|
reservation.checkin_date = reservation.reservation_date(
reservation.checkin_datetime
)
reservation.checkin_time = reservation.reservation_time(
reservation.checkin_datetime
)
end
end
def self.reservations_checkout_setter(reservations)
reservations.each do |reservation|
reservation.checkout_date = reservation.reservation_date(
reservation.checkout_datetime
)
reservation.checkout_time = reservation.reservation_time(
reservation.checkout_datetime
)
end
end
def hotel_name
room.hotel.name
end
def increase_room_inventory
room.update(inventory: (room.inventory += number_of_rooms))
end
def self.reservation_checkin_setter(reservation)
reservation.checkin_date = reservation.reservation_date(
reservation.checkin_datetime
)
reservation.checkin_time = reservation.reservation_time(
reservation.checkin_datetime
)
end
def self.reservation_checkout_setter(reservation)
reservation.checkout_date = reservation.reservation_date(
reservation.checkout_datetime
)
reservation.checkout_time = reservation.reservation_time(
reservation.checkout_datetime
)
end
def alter_room_inventory(orginal_number)
if number_of_rooms != orginal_number.to_i
room = Room.find(room_id)
room.update(inventory: (room.inventory += orginal_number.to_i))
answer = self.room_available?(room.room_type)
if answer[0]
self.decrease_room_inventory
else
room.update(inventory: (room.inventory -= orginal_number.to_i))
end
answer
else
false
end
end
def room_available?(room_type)
if Room.find(room_id).inventory == 0
message = "Unfortunately, all of those #{room_type.name} rooms have "\
"been reserved. Please select another room"
return false, message
elsif number_of_rooms > Room.find(room_id).inventory
message = "Unfortunately, your desired quantity of the " \
"#{room_type.name} room is not available. Please select another " \
"room, or reserve less rooms of this type"
return false, message
else
[true]
end
end
def user_view_reservation_date(booking_datetime)
booking_datetime.to_date.strftime('%A, %B %d, %Y')
end
def user_view_reservation_time(booking_datetime)
booking_datetime.to_time.strftime('%l:%M %P')
end
def total_nights
(checkout_datetime.to_date - checkin_datetime.to_date).to_i
end
def total_price
nights = self.total_nights == 0? 1 : self.total_nights
cost = nights * room.room_rate * number_of_rooms
taxes = cost * 0.15
cost + taxes
end
end
_reservation.html.erb
<div>
<h3><%= reservation.room_name %> at <%= reservation.hotel_name %></h3>
<ul>
<strong>Check In: </strong>
<%= reservation.user_view_reservation_time(reservation.checkin_time) %> on
<%= reservation.user_view_reservation_date(reservation.checkin_date) %>
<br />
<strong>Check out: </strong>
<%= reservation.user_view_reservation_time(reservation.checkout_time) %> on
<%= reservation.user_view_reservation_date(reservation.checkout_date) %>
<br />
<strong>Rooms: </strong>
<%= reservation.number_of_rooms %><br />
</ul>
<h3>Your Rate</h3>
<ul>
<strong>Total Nights: </strong>
<%= reservation.total_nights %><br />
<strong>Average Nightly Rate: </strong>
<%= number_to_currency(reservation.room.room_rate) %><br />
<strong>Estimated Total Price: </strong>
<%= number_to_currency(reservation.total_price) %><br />
</ul>
<%= button_to 'Edit',
edit_reservation_path(reservation, reservation.id), method: 'get',
class: 'btn btn-large btn-primary' %><br />
<%= button_to 'Delete', reservation_path(reservation), method: 'delete',
data: { confirm: 'Are you sure you want to delete this reservation?' },
class: 'btn btn-large'%>
</div>
reservations_controller.rb
class ReservationsController < ApplicationController
before_action :require_login
before_action :set_reservation, only: [:edit, :update, :destroy]
def index
#reservations = Reservation.users_reservations(current_user)
Reservation.reservations_checkin_setter(#reservations)
Reservation.reservations_checkout_setter(#reservations)
end
def create
#reservation = Reservation.new(reservation_params)
#reservation.checkin_date=(reservation_params[:checkin_date])
#reservation.checkin_time=(reservation_params[:checkin_time])
#reservation.checkout_date=(reservation_params[:checkout_date])
#reservation.checkout_time=(reservation_params[:checkout_time])
#reservation.convert_to_datetime
#room_type = RoomType.find(params[:reservation][:room_type_id])
result = #reservation.room_available?(#room_type)
if result[0]
if #reservation.save
#reservation.decrease_room_inventory
redirect_to reservations_path,{notice: "Your reservation " \
"for the #{#reservation.room_name} has been made, $0 are due today"}
else
render :'room_types/show'
end
else
redirect_to room_path(#reservation.room.hotel),
{alert: "#{result[1]}"}
end
end
def edit
if #reservation.user_id == current_user.id
Reservation.reservation_checkin_setter(#reservation)
Reservation.reservation_checkout_setter(#reservation)
render :edit
else
flash[:alert] = "You don't have permission to edit that reservation."
redirect_to reservations_path
end
end
def update
#reservation.checkin_date=(reservation_params[:checkin_date])
#reservation.checkin_time=(reservation_params[:checkin_time])
#reservation.checkout_date=(reservation_params[:checkout_date])
#reservation.checkout_time=(reservation_params[:checkout_time])
#reservation.convert_to_datetime
#reservation.number_of_rooms = reservation_params[:number_of_rooms]
result = #reservation.alter_room_inventory(
params[:reservation][:orginal_number_of_rooms]
)
if !result || result[0]
if #reservation.save
redirect_to reservations_path,{notice: "Your reservation " \
"for the #{#reservation.room_name} has been updated."}
else
render :edit
end
else
redirect_to reservations_path, {alert: "#{result[1]}"}
end
end
def destroy
#reservation.increase_room_inventory
#reservation.delete
redirect_to reservations_path,{notice: "Your reservation for " \
"#{#reservation.checkin_datetime.strftime('%A, %B %d, %Y')} has " \
"been deleted."}
end
private
def set_reservation
#reservation = Reservation.find_by(id: params[:id])
end
def reservation_params
params.require(:reservation).permit(
:checkin_date,
:checkin_time,
:checkout_date,
:checkout_time,
:number_of_rooms,
:room_id,
:user_id
)
end
end
user.rb
class User < ActiveRecord::Base
has_many :reservations, dependent: :destroy
has_many :rooms, through: :reservations
has_many :addresses, dependent: :destroy
validates_presence_of :name
has_secure_password
validates_associated :addresses, unless:
Proc.new { |user| user.provider.present?}
def addresses_attributes=(addresses_attributes)
addresses_attributes.values.each do |address_attributes|
if address_attributes.keys.include?('id')
address = self.addresses.find(address_attributes[:id])
address.update_attributes(address_attributes)
else
self.addresses.build(address_attributes)
end
end
end
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.provider = auth.provider
user.uid = auth.uid
user.name = auth.info.name
user.password = SecureRandom.hex
end
end
def update_room_inventory
reservations.each do |reservation|
reservation.increase_room_inventory
end
end
end
routes.rb
Rails.application.routes.draw do
get '/auth/:provider/callback', to: 'sessions#github'
resources :addresses, only: [:new, :create, :destroy]
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users
resources :reservations, only: [:index, :edit, :update, :destroy]
resources :rooms, only: :show do
resources :room_types, only: :show
resources :reservations, only: :create
end
root 'hotels#index'
end
create_reservations.rb
class CreateReservations < ActiveRecord::Migration
def change
create_table :reservations do |t|
t.references :room, index: true, foreign_key: true
t.references :user, index: true, foreign_key: true
t.integer :number_of_rooms, default: 1
t.datetime :checkin_datetime
t.datetime :checkout_datetime
t.timestamps null: false
end
end
end
I see that the error is from
def future_checkin_time as the error message says
Checkin time must be a valid current or future time
Also as per your code in the error message checkin time value must be shown. Can you please print and check if the value is being captured properly?

Rails elasticsearch with multiple models

Thus far I have implemented a basic search with eleasticsearch. Insert a keyword and find the item according to the title/description.
Now I'm trying to sort the results according to distance from the users current location, but don't know how.
I have two models, the items.rb contains the item info and the account.rb has the address of the user that uploaded the item.
This is what I have done thus far:
item.rb
require 'elasticsearch/model'
class Item < ApplicationRecord
mount_uploader :image, ImageUploader
belongs_to :category
belongs_to :user
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
settings index: { number_of_shards: 1 } do
mappings dynamic: 'false' do
indexes :title, analyzer: 'english', index_options: 'offsets'
indexes :description, analyzer: 'english'
end
end
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
fields: ['title^10', 'description']
}
},
highlight: {
pre_tags: ['<em>'],
post_tags: ['</em>'],
fields: {
title: {},
description: {},
}
}
}
)
end
end
# Delete the previous articles index in Elasticsearch
Item.__elasticsearch__.client.indices.delete index: Item.index_name rescue nil
# Create the new index with the new mapping
Item.__elasticsearch__.client.indices.create \
index: Item.index_name,
body: { settings: Item.settings.to_hash, mappings: Item.mappings.to_hash }
# Index all Item records from the DB to Elasticsearch
Item.import
account.rb
require 'elasticsearch/model'
class Account < ApplicationRecord
geocoded_by :full_address
after_validation :geocode, if: ->(obj){ obj.full_address.present? }
def full_address
[street, city, state, zip_code, country].join(",")
end
def location
[longitude.to_f, latitude.to_f]
end
ELASTICSEARCH_MAX_RESULTS = 25
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
include Elasticsearch::Model::Indexing
mapping do
indexes :location, type: 'geo_point'
indexes :city, type: 'string'
indexes :state, type: 'string'
end
def as_indexed_json(_options = {})
as_json(only: %w(city state))
.merge(location: {
lat: lat.to_f, lon: lon.to_f
})
end
def self.search(query = nil, options = {})
options ||= {}
# empty search not allowed, for now
return nil if query.blank? && options.blank?
# define search definition
search_definition = {
query: {
bool: {
must: []
}
}
}
unless options.blank?
search_definition[:from] = 0
search_definition[:size] = ELASTICSEARCH_MAX_RESULTS
end
# query
if query.present?
search_definition[:query][:bool][:must] << {
multi_match: {
query: query,
fields: %w(city state),
operator: 'and'
}
}
end
# geo spatial
if options[:lat].present? && options[:lon].present?
options[:distance] ||= 100
search_definition[:query][:bool][:must] << {
filtered: {
filter: {
geo_distance: {
distance: "#{options[:distance]}mi",
location: {
lat: options[:lat].to_f,
lon: options[:lon].to_f
}
}
}
}
}
end
__elasticsearch__.search(search_definition)
end
end
# Delete the previous articles index in Elasticsearch
Account.__elasticsearch__.client.indices.delete index: Account.index_name rescue nil
# Create the new index with the new mapping
Account.__elasticsearch__.client.indices.create \
index: Item.index_name,
body: { settings: Account.settings.to_hash, mappings: Account.mappings.to_hash }
# Index all Item records from the DB to Elasticsearch
Account.import
search_controller.rb
class SearchController < ApplicationController
def show
#items = Item.find(params[:id])
end
def search
if params[:q].nil?
#items = []
else
#items = Item.search params[:q]
end
end
end
search.html.erb
<%= form_for search_path, method: :get do |f| %>
<p>
<%= f.label "Search for" %>
<%= text_field_tag :q, params[:q] %>
<%= submit_tag "Nearby", name: nil %>
</p>
<% end %>
<ul>
<% #items.each do |item| %>
<li>
<h3>
<%= link_to item.try(:highlight).try(:title) ? item.highlight.title[0].html_safe : item.title,
controller: "search",
action: "show",
id: item._id%>
</h3>
<% if item.try(:highlight).try(:description) %>
<% item.highlight.description.each do |snippet| %>
<p><%= snippet.html_safe %>...</p>
<% end %>
<% end %>
</li>
<% end %>
You should index the lat/lng on each item using the referenced account, don't index another document for the account. Though ES can express some relations, remember it isn't a relational DB.

Parameter missing error(rails)

I am facing an error that when ever I try to call the function finalized_request it throws me an error saying "param is missing or the value is empty: finalizedeal". Since I am new to this I can't figure out what am I doing wrong(I am new to ROR).
Request_controller.rb
class RequestsController < ApplicationController
before_action :set_request, only: [:show, :edit, :update, :destroy]
# GET /requests
# GET /requests.json
def index
#categories_list = Category.getAll()
end
def active
user = session[:user]
#requests = Array.new
#tag = Array.new
#requests = Request.getRequestByUser(user)
#requests.each.with_index do |request, index|
if request != nil
#tag[index] = Array.new
request[:tag_id].each do |t|
#tag[index] << Tag.getTag(t)
end
end
end
end
# GET /requests/1
# GET /requests/1.json
def show
#user = User.getUser(#request[:user_id])
#tag = Array.new
#request[:tag_id].each do |cate|
#tag << Tag.getTag(cate)
end
end
# GET /requests/1/edit
def edit
#tag = Array.new
#request[:tag_id].each do |cate|
#tag << Tag.getTag(cate)
end
end
# POST /requests
def post_request
tags_arr = params[:tags] ;
#=begin
#categories = Array.new ;
#if tags != nil
# tags.each do |tag|
# category = Category.createCategoryIfNotExist(tag)
# if(category != nil)
# categories << category[:_id]
# end
# end
#end
#=end
tags = Array.new ;
if tags_arr != nil
tags_arr.each do |t|
tag = Tag.createTagIfNotExist(t)
if(tag != nil)
tags << tag[:_id]
end
end
end
request_data = request_params
user_id = session[:user]
request_data[:tag_id] = tags
request_data[:user_id] = user_id
#request_ = Request.createRequest(request_data)
if #request_
flash[:notice] = "Request Post successfully."
redirect_to :action => "active"
end
end
# PATCH/PUT /requests/1
# PATCH/PUT /requests/1.json
def update
#tags = params[:tags] ;
#categories = Array.new ;
#if tags != nil
# tags.each do |tag|
# category = Category.createCategoryIfNotExist(tag)
# if(category != nil)
# categories << category[:_id]
# end
# end
#end
tags_arr = params[:tags] ;
tags = Array.new ;
if tags_arr != nil
tags_arr.each do |t|
tag = Tag.createTagIfNotExist(t)
if(tag != nil)
tags << tag[:_id]
end
end
end
Rails.logger.info("RequestsParams: #{request_params.inspect}")
request_data = request_params
if request_data[:is_service] != "on"
request_data[:is_service] = "off"
end
user_id = session[:user]
request_data[:tag_id] = tags
request_data[:user_id] = user_id
if Request.updateRequest(#request,request_data)
flash[:notice] = "Request has been Edited successfully."
redirect_to :action => "active"
end
end
def delete_request ()
if Request.delete_request(params[:id])
flash[:notice] = "Request has been Deleted successfully."
render :json => "great"
end
end
# GET /requests
def finalize_request()
finalizedrequest = finalizedRequest_params
request = Request.getRequest(finalizedrequest[:title])
finalizedrequest[:title] = request[:title]
Request.delete_request(request[:_id])
FinalizedDeal.createFinalizedRequest(finalizedrequest)
redirect_to :action => "bookmark"
end
# GET /requests
def bookmark
user = session[:user]
#requests = Array.new
#tag = Array.new
#requests = Request.getRequestByUser(user)
#requests.each.with_index do |request, index|
if request != nil
#tag[index] = Array.new
request[:tag_id].each do |t|
#tag[index] << Tag.getTag(t)
end
end
end
end
# GET /requests
def bookmark_request
data = params[:d]
bookmarked_against_Request = Request.getRequest(1)
request_bookmarked = Request.getRequest(data)
request_bookmarked_2 = request_bookmarked
bookmarked_against_Request_2 = bookmarked_against_Request
Rails.logger.info("Bookmark 2: #{bookmarked_against_Request_2.inspect}")
#bookmarked_against_Request_2[:favourites] << request_bookmarked[:id]
#request_bookmarked_2[:favourites_of] << bookmarked_against_Request[:id]
#hello
#Request.updateRequest(request_bookmarked , request_bookmarked_2)
#Request.updateRequest(bookmarked_against_Request , bookmarked_against_Request_2)
redirect_to :action => "bookmark"
end
private
# Use callbacks to share common setup or constraints between actions.
def set_request
#request = Request.getRequest(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def request_params
params.require(:request).permit(:title, :description, :type , :is_service , :required_user_location , :required_product_location ,:Upper_price_range , :lower_price_range , :negotiable , :type , :tags , :category_id)
end
def finalizedRequest_params
params.require(:finalizedeal).permit(:title , :description)
end
end
finalized_deal.rb
class FinalizeDeal
include Mongoid::Document
field :deal_details, type: String
field :categories, type: Array
field :owner_user, type: MongoId
field :corsponing_user, type: MongoId
field :title, type: String
field :corresponding_product, type: String
field :meeting_date, type: String
field :date_finalized, type: String
field :description, type: String
class << self
def getRequestByUser(user_id)
requests = where(user_id: user_id).to_a
if requests
requests
end
end
def getFinzlizedRequest(req)
request = find(req)
if request
request
end
end
def createFinalizedRequest(req_data)
request = self.new(req_data)
if request.save
request
end
end
def updateFinalizedRequest(request,req_data)
if request.update(req_data)
request
end
end
def delete_FinalizedRequest(req_id)
if find(req_id).delete
true
end
end
end
end
request.html.erb
div id="form-details-modal-lbms" class="reveal-modal" data-reveal>
<h3>Enter Contract Details:</h3>
<!--<form>-->
<%= form_tag({controller: "requests", action: "finalize_request"}, method: "GET",id:"post-form-lbms" ,data: {abide: ''}) %>
<input type="hidden" id="currect_opened_req_id" value="" name="FinalizeDeal[title]"/>
<select name="meeting-id">
<option value="1">Meeting 1</option>
<option value="2">Meeting 2</option>
</select>
<label for="details-lbms">Details</label>
<textarea id="details-lbms" name="FinalizeDeal[description]"></textarea>
<button class="button tiny">
Submit
</button>
</form>
<a class="close-reveal-modal">×</a>
</div>
Please tell me what am I doing wrong. I am also posting a link to the screenshot of the error
http://tinypic.com/r/n6t8w2/8
http://tinypic.com/r/33kdq1k/8
The code is complaining because you are requiring the :finalizedeal parameter (but apparently you are not passing it along) by adding this .require(:finalizedeal) to this code:
def finalizedRequest_params
params.require(:finalizedeal).permit(:title , :description)
end
So one solution would be to simply remove the require part. Like so:
params.permit(:title , :description)
#require source
Ensures that a parameter is present.

form_for without ActiveRecord, form action not updating

I'm using an API instead of a database, so I'm not using ActiveRecord but ActiveModel (I mostly did like here: railscasts.com/episodes/219-active-model)
Thing is, when I try to edit an item (in my case a parking), the action of the form still remains the action of the create and not update.
so when I go on /parkings/2/edit to edit a parking, the form is still:
<form accept-charset="UTF-8" action="/parkings" class="form-horizontal" id="new_parking" method="post">
when it should be more like that with the put hidden field and the parkings/2 as the action:
<form accept-charset="UTF-8" action="/parkings/2" class="form-horizontal" id="edit_parking" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="_method" type="hidden" value="put" />
Anybody knows where the method & action of the form_for is set according to the route? What I'm trying to do is be as close as if I was using ActiveRecord with a database.
Here is some code :
_form.html.erb
<%= form_for(#parking, :html => { :class => "form-horizontal" }) do |f| %>
...
<% end %>
edit.html.erb & new.html.erb, simply has
<%= render 'form' %>
Controller
class ParkingsController < ApplicationController
def index
#parkings = Parse.get("Parking")
respond_to do |format|
format.html
format.json { render :json => #parking }
end
end
def new
#parking = Parking.new
respond_to do |format|
format.html
format.json { render :json => #parking }
end
end
def edit
#parking = Parking.find(params[:id])
respond_to do |format|
format.html
format.json { render :json => #parking }
end
end
def create
#parking = Parking.new(params[:parking])
if (#parking.save)
flash[:success] = "Parking was just added!"
redirect_to :action => "new"
else
render :action => "new"
end
end
def update
# Testing
parking = Parse.get("Parking", params[:id])
parking.delete("updatedAt")
parking["name"] = params[:parking][:name]
parking.save
redirect_to :action => "index"
end
Model
class Parking
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :address, :city, :longitude, :latitude, :contributor_name, :contributor_email
validates_presence_of :name, :address, :city, :longitude, :latitude
#id = nil
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def self.find(id)
#id = id
raw = Parse.get("Parking", #id.to_s)
parking = Parking.new
parking.name = raw["name"]
parking.address = raw["address"]
parking.city = raw["city"]
parking.longitude = raw["location"]["longitude"]
parking.latitude = raw["location"]["latitude"]
parking.contributor_name = raw["contributorName"]
parking.contributor_email = raw["contributorEmail"]
return parking
end
def save
if (!valid?)
return false
else
parking = Parse::Object.new("Parking")
data =
{
:longitude => longitude.to_f,
:latitude => latitude.to_f
}
point = Parse::GeoPoint.new(data)
parking["location"] = point
parking["name"] = name
parking["address"] = address
parking["city"] = city
parking["contributorName"] = contributor_name
parking["contributorEmail"] = contributor_email
if (parking.save)
return true
end
end
end
def persisted?
false
end
end
Please note that the create is working and if I add the id of my parking in the form action="" using the Web Inspector or Firebug, and add :method => "put" in my form_for, my record successfully update.
The real problem here is really the form_for action & method who doesn't get updated when I'm editing a parking and remains like if I was adding a new one.
I'm still learning Rails, so sorry if some infos aren't clear!
Thank you!
--- SOLUTION ---
persisted? shouldn't only return false, and my model needed to define a method that returns the id of the object (so they can update the action="") so here's is my updated model:
class Parking
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :objectId, :name, :address, :city, :longitude, :latitude, :contributor_name, :contributor_email
validates_presence_of :name, :address, :city, :longitude, :latitude
#id = nil
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
def self.find(id)
raw = Parse.get("Parking", id.to_s)
parking = Parking.new
parking.objectId = id
parking.name = raw["name"]
parking.address = raw["address"]
parking.city = raw["city"]
parking.longitude = raw["location"]["longitude"]
parking.latitude = raw["location"]["latitude"]
parking.contributor_name = raw["contributorName"]
parking.contributor_email = raw["contributorEmail"]
return parking
end
def save
if (!valid?)
return false
else
parking = Parse::Object.new("Parking")
data =
{
:longitude => longitude.to_f,
:latitude => latitude.to_f
}
point = Parse::GeoPoint.new(data)
parking["location"] = point
parking["name"] = name
parking["address"] = address
parking["city"] = city
parking["contributorName"] = contributor_name
parking["contributorEmail"] = contributor_email
if (parking.save)
return true
end
end
end
def update_attributes(aParking)
parking = Parse.get("Parking", #id.to_s)
parking.delete("updatedAt")
parking["name"] = aParking["name"]
parking.save
return true
end
def destroy
parking = Parse.get("Parking", #id)
#parking.parse_delete
end
def id
return self.objectId
end
def persisted?
!(self.id.nil?)
end
end
I think your problem is in your model's persisted? method. Since it always returns false, Rails always thinks it's building a form for a newly created record, so it uses POST and submits to the collection URL.
You need some sort of logic in that method so that existing records return true and new records return false.
Hi friend you can to tell the form builder which method to use.So try
<%= form_for(#parking, :method => ["new", "create"].include?(action_name) ? :post : :put,
:html => { :class => "form-horizontal" }) do |f| %>
...
<% end %>
If you are not using ActiveRecord you should use 'form_tag' instead 'form_for'

Resources