Location model as polymorphic association - ruby-on-rails

I hope I'm forming this question correctly. But I'm trying to create a location model that has a geocoded address and that address is able to be located on a map using gmap for rails.
My issue is associating my Location model with other application models. Currently I'm attempting to have a location field within my post form.
My application is as followed using the geocoder and gmaps for rails gems.
class Location < ActiveRecord::Base
belongs_to :locatable, polymorphic: true
belongs_to :post
geocoded_by :address
acts_as_gmappable
after_validation :geocode
validates :address, presence: true
validates :latitude, presence: true
validates :longitude, presence: true
def gmaps4rails_address
"#{address}"
end
validates :locatable, presence: true
end
Post model
class Post < ActiveRecord::Base
has_one :location, as: :locatable , :dependent => :destroy
accepts_nested_attributes_for :locations,:reject_if =>:all_blank ,allow_destroy: true
end
Controllers
Post Controller
def new
#post= current_user.posts.build
end
def create
#post = current_user.posts.new(post_params)
#post = Location.new
if #post.save
redirect_to root_path
else
render 'new'
flash[:error] = !"
end
end
def post_params
params.require(:post).permit(locations_attributes[:address,:latitude,:longitude, :locatable_id, :locatable_type, :gmaps])
end
Locations Controller
class LocationsController < ApplicationController
def new
#location = Location.new
end
def create
#location = Location.new(params[:location])
end
def destroy
#location.destroy
respond_to do |format|
format.html { redirect_to locations_url, notice: 'Location was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def location_params
params.require(:location).permit(:address, :latitude, :longitude, :locatable_id, :locatable_type, :gmaps)
end
end
My code might be snippet out but my overall issue is happening within the controller I have everything going right. The location field within my post form is a nested form of the model location, the address field is geocoded and has a location search for the address input. My problem arises when submitting the post, I've tried several methods but I cannot get the location to save to post model. Any help would be amazingly helpful.

Related

How do I create a page without a model?

I'm working on an app which has many 'Activities'. Each 'Activity' has many 'Ranks'. I'd like each 'Activity' to have a page called grading, where the user can see a list of all of that activity's ranks and conveniently update them. I imagine the URL would be something like http://localhost:3000/activities/21/grading
I'm already using http://localhost:3000/activities/21/edit for its intended purpose.
I don't need a model for gradings, as I don't need to save any grading records.
I know exactly what to put in the view, I'm just unsure what to add to the controller and routes files. Other people have worked on this app but I'm unable to contact them.
Routes
resources :activities do
collection do
get 'scheduled_classes'
end
end
resources :ranks
end
activities_controller
class ActivitiesController < ApplicationController
def new
#activity = Activity.new
#activity.timeslots.build
#activity.ranks.build
end
def create
#activity = current_club.activities.new(activity_params)
if #activity.save
flash[:success] = "New class created!"
redirect_to activity_path(#activity)
else
render 'new'
end
end
def edit
#activity = current_club.activities.find_by(id: params[:id])
#active_ranks = #activity.ranks.where(active: true)
if !#activity.active?
redirect_to activities_path
else
#activity.timeslots.build
end
end
def update
#activity = current_club.activities.find_by(id: params[:id])
if #activity.update_attributes(activity_params)
flash[:success] = "Class updated!"
redirect_to edit_activity_path(#activity)
else
render 'edit'
end
end
def show
#activity = current_club.activities.find_by(id: params[:id])
#active_ranks = #activity.ranks.where(active: true)
if #activity.nil?
redirect_to root_url
elsif !#activity.active?
redirect_to activities_path
end
end
def index
#activities = current_club.activities.all
end
def destroy
#activity = current_club.activities.find_by(id: params[:id])
if #activity.nil?
redirect_to root_url
else
#activity.destroy
flash[:success] = "Class deleted"
redirect_to activities_path
end
end
end
private
def activity_params
params.require(:activity).permit(:name, :active,
:timeslots_attributes => [:id,
:time_start,
:time_end,
:day,
:active,
:schedule],
:ranks_attributes => [:id,
:name,
:position,
:active])
end
end
activity
class Activity < ApplicationRecord
belongs_to :club
has_many :timeslots, dependent: :destroy
accepts_nested_attributes_for :timeslots,:allow_destroy => true
has_many :ranks, dependent: :destroy
has_many :attendances, dependent: :destroy
accepts_nested_attributes_for :ranks
validates :club_id, presence: true
validates :name, presence: true, length: { maximum: 50 }
end
Your routes don't need to have an associated model or resource.
resources :activities do
collection do
get 'scheduled_classes'
end
member do
get :grading
end
end
will match to activities#grading
See https://guides.rubyonrails.org/routing.html#adding-member-routes for more info.
As you want to add a route on a particular activity, you should add member route on the activity like below,
resources :activities do
collection do
get 'scheduled_classes'
end
get :grading, on: :member
end
Apart from this, you have to add method in ActivitiesController for this route like below,
def grading
#activity = Activity.find_by(id: params[:id])
# do more here
end
In view files, you can create grading.html.erb under activities resources and put your view code there.

Ruby On Rails [Carrierwave]: Cannot delete image

I'm a newbie in rails and trying to implement image uploading to ftp with 'carrierwave-ftp' gem. For image uploading, I have two controllers. First one is 'events_controller' while the second one is 'events_pictures_controller'.
Pictures are getting uploading to ftp. But the problem is that when I'm deleting a single picture, it is destroying the entire event. Please help!
Here is my Events Model:
class Event < ActiveRecord::Base
has_many :event_pictures, dependent: :destroy
accepts_nested_attributes_for :event_pictures, allow_destroy: true
validates_presence_of :name, :date
end
Here is my EventPictures Model:
class EventPicture < ActiveRecord::Base
mount_uploader :picture_title, EventPicturesUploader
validates_presence_of :picture_title
belongs_to :event, dependent: :destroy
end
Events Controller:
def index
#events = Event.all.order('date DESC')
end
def show
#event_pictures = #event.event_pictures.all
end
def new
#event = Event.new
#event_picture = #event.event_pictures.build
end
def edit
end
def create
#event = Event.new(event_params)
respond_to do |format|
if #event.save
params[:event_pictures]['picture_title'].each do |a|
#event_picture = #event.event_pictures.create!(:picture_title => a, :event_id => #event.id)
end
format.html { redirect_to #event, notice: 'Event was successfully created.' }
else
format.html { render :new }
end
end
end
def destroy
#event = Event.find params[:id]
#event.destroy
redirect_to events_url
end
private
def set_event
#event = Event.find(params[:id])
end
def event_params
params.require(:event).permit(:name, :date, event_pictures_attributes: [:id, :event_id, :picture_title])
end
This is the Destroy method in EventPictures Controller
def destroy
#event_picture = EventPicture.find params[:id]
#event_picture.destroy
redirect_to "events_url"
end
Meanwhile in the events.show.html.erb, I have this:
<% #event_pictures.each do |p| %>
<%= link_to image_tag(p.picture_title_url, :class => 'event-img'), image_path(p.picture_title_url) %>
<%= link_to 'Delete', p, method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
In your EventPicture model you have dependent: :destroy on the association which means that when the picture will deleted the corresponding events too. So just edit the association and make it:
belongs_to :event
And you have dependent destroy on the Event model so when a event will be deleted the corresponding pictures too will get deleted which is correct.
Hope this helps.
I believe your error lies with this line
belongs_to :event, dependent: :destroy
This is telling the EventPicture model to delete its parent model Event when it is deleted.
Replace with
belongs_to :event

decent_exposure creates double entries each time

I'am using decent_exposure gem and cocoon gem for nested forms and after each create or update I am getting duplicate entries. What am I doing wrong? X_X
Controller
class Admin::DealsController < ApplicationController
expose :deals
expose :deal, attributes: :deal_params
def create
if deal.save
redirect_to [:admin, deal], notice: 'Deal was successfully created.'
else
render :new
end
end
def update
if deal.update(deal_params)
redirect_to [:admin, deal], notice: 'Deal was successfully updated.'
else
render :edit
end
end
private
def deal_params
params.require(:deal).permit :title, :end_date,
deal_variants_attributes: [:id, :title, :description, :price, :discount, :_destroy]
end
end
Model
class Deal < ActiveRecord::Base
has_many :deal_variants
accepts_nested_attributes_for :deal_variants, reject_if: :all_blank, allow_destroy: true
end
Thanks in advance!
I met the same problem today and here is my solution and explanation:
This happens because decent_exposure already sets required attributes for you, and when you call .update(deal_params) it duplicates entries since first instance of DealVariant was set by decent_exposure, and second one was set by .update(deal_params) call. What you need to do instead is to use simple .save method in both create and update actions.

Foreign key is still nil after relation was built

I have problem while creating new user with address. I create record in Users and Addresses table, but foreign key to address in user is still nil.
class User < ActiveRecord::Base
belongs_to :address
accepts_nested_attributes_for :address
end
class Address < ActiveRecord::Base
has_one :user
end
def new
#user = User.new
#user.build_address
end
def create
#user = User.new(user_params)
if #user.save
flash[:notice] = "Your account has been created."
redirect_to signup_url
else
flash[:notice] = "There was a problem creating you."
render :action => :new
end
end
private
def user_params
params.require(:user).permit(
:first_name,
:last_name,
:email,
:password,
:password_confirmation,
address_attributes: [:id, :city]
)
end
end
Thank you.
You mixed up relation types.
Try this:
class User < ActiveRecord::Base
has_one :address
end
class Address < ActiveRecord::Base
belongs_to :user
end
Also your code is structured funny, two models and then some methods out of their context. I hope it's just a misprint. If not, put everything except Address model into User model.

Weird has_many :through new record form issue

I'm having a regular for with checkboxes for my has_many :through relation. My problem is that I can't create a new project and have checkboxes checked. I get a validation error "Users is invalid". This is really weird.
If I create a project with no user checked it works and I can check them when I'm editing the project.
- User.each do |user|
%label.checkbox{title: user.email}
= check_box_tag 'project[user_ids][]', user.id, #project.user_ids.include?(user.id)
= truncate(user.full_name, length: 16)
So in short: I can edit projects but not create new ones. Any ideas?
EDIT:
I have three models, User, Project, Projectship where the latest is the relation between the others. It's when I'm trying to create a project and pass user relations to it my problem occurs. When editing everything works like a charm.
User
id
email
has_many :projectships, dependent: :destroy
has_many :projects, through: :projectships
Project
id
name
has_many :projectships, dependent: :destroy
has_many :users, through: :projectships
Projectship
id
user_id
project_id
belongs_to :project
belongs_to :user
validates :project_id, presence: true
validates :user_id, presence: true
ProjectsController:
# GET /projects/new
def new
#project = Project.new
end
# POST /projects
def create
#project = Project.new(project_params)
if #project.save
redirect_to #project, notice: t('flash.project_created')
else
render :new
end
end
# GET /projects/:id/edit
def edit
#project = Project.includes(:users).find(params[:id])
end
# PUT /projects/:id
def update
#project = Project.find(params[:id])
if #project.update_attributes(project_params)
redirect_to :back, notice: t('flash.project_updated')
else
render :edit
end
end
private
def project_params
params.require(:project).permit(
:client_id, :currency, :description, :end_date, :estimated_hours,
:fixed_price, :hourly_rate, :name, :start_date, :status,
:billable_type, :user_ids
)
end
P.S I'm using 4.0.0.beta D.S
To store users_ids the model needs to be saved and that's way it didn't work. So now I store the ids in the create action and than add them directly after I save the project.

Resources