cannot access attribute in table with many to many relationship - ruby-on-rails

I have two tables set up in a many to many relationship: maintenance_schedule and service_type. I'm trying to make a dropdown list on the form for maintenance_schedule that allows me to select service_type_name from the service_type table.
My models are set up like this:
class ServiceType < ActiveRecord::Base
attr_accessible :service_type_name
has_many :maintenance_schedules, :through => :schedule_services
end
class MaintenanceSchedule < ActiveRecord::Base
attr_accessible :maintenance_schedule_date
has_many :service_types, :through => :schedule_services
accepts_nested_attributes_for :service_types
end
class ScheduleService < ActiveRecord::Base
attr_accessible :maintenance_schedule_id, :service_type_id
belongs_to :maintenance_schedule
belongs_to :service_type
end
my index page is giving me undefined method `service_type_name'
<p id=<%="maintenance_schedule_#{maintenance_schedule.id}"%>>
<div>service type: <%= maintenance_schedule.service_types.service_type_name %></div>
<%= link_to "Delete", maintenance_schedule_path(maintenance_schedule.id), :method => :delete, :class => "delete", :confirm => "Are you so sure?"%>
<%= link_to "Edit", edit_maintenance_schedule_path(maintenance_schedule)%>
This is my index method in the controller
def index
#maintenance_schedules = MaintenanceSchedule.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #maintenance_schedules}
end
end

Related

how to post the values from chat controller to other tables using rails

I wanted know, how to post the values from the chat controller to other tables using rails.
class Chat < ApplicationRecord
belongs_to :user
has_many :visitors
has_many :themes
class Colour < ApplicationRecord
has_many :themes
has_many :chatbots, through: :themes
has_many :user_avatars, through: :themes
validates :hash_code, presence: true
class UserAvatar < ApplicationRecord
belongs_to :user
has_many :themes
has_many :chatbots, through: :themes
has_many :colours, through: :themes
validates :image_icon,:presence => true
class Theme < ApplicationRecord
belongs_to :chatbot
belongs_to :user_avatar
belongs_to :colour
validates :position, presence: true
Here in chat i should able to select colour, position, user avatar and it should be saved in those table, but here I dont know how to post the values from chat controller to other tables (for selecting the colour I am using color-picker)
code for chat_controller is given below
class ChatsController < ApplicationController
layout 'dashboard'
before_action :authenticate_user!
def index
#chatbot = Chatbot.all.where(:user_id => current_user.id)
end
def new
#chatbot = Chatbot.new
end
def show
#chatbot = Chatbot.find_by_id(params[:id])
end
def edit
#chatbot = Chatbot.find_by_id(params[:id])
end
def destroy
#chatbot = Chatbot.find_by_id(params[:id])
if #chatbot.destroy
flash[:success] = "Successfully deleted!"
else
flash[:success] = "Deletion Failed!"
end
end
def create
#colour = Colour.new(colour_params)
if #colour.save
redirect_to chatbots_path
end
end
private
def colour_params
params.require(:colour).permit(:hash_code)
end
def chatbot_params
params.require(:chatbot).permit(:id,:name,:description,:embed_id)
end
end
show.html.erb
<%= form_for #chatbot, :url => {:controller => 'chatbots', :action =>
"create" }, html: { method: :post } do |f| %>
<%= f.label "Select Theme Color" %>
<%= f.hidden_field :colour_ids %>
<%= f.text_field :colour, class: "color-picker", id: "theme-picker" %>
<%= f.submit "Save" , class: "btn btn-primary"%>
<% end %>
# code for position-select
# code for user avatar

How to delete record in a table and in its sub-table?

I want to create a link to delete a record and it's sub record in a foreign table.
My models are like this :
class Cv < ActiveRecord::Base
has_many :formation
end
class Formation < ActiveRecord::Base
belongs_to :cv
validates :cv_id, presence: true
end
in my index view I have :
<%- #cv.each do |p| -%>
<%= link_to p.nom, cvsindex2_path(p) %>
<%= link_to 'delete', cvsdestroy_path(p) %></br>
<%- end -%>
My route :
cvsdestroy DELETE /cvs/:id(.:format)
How can I do that?
Thanks in advance.
If you will add dependent destroy to your relationship it will delete all its associated records from foreign key tables also.
class Cv < ActiveRecord::Base
has_many :formation, dependent: destroy
end
You need to add dependent: :destroy to your formation model in order to delete the associated record.
class Formation < ActiveRecord::Base
belongs_to :cv, dependent: :destroy
validates :cv_id, presence: true
end
And also change formation to formations in your cv model as you have has_many relation.
Update
You should also change your Delete link to like this
<%= link_to 'delete', cvsdestroy_path(p), method: :delete %>
Thank you that work with this
<%= link_to 'delete', #cv, :data => {:confirm => 'Are you sure?'}, :method => :delete %>
and
def destroy
#cvdestroy = Cv.find(params[:id])
#cvdestroy.destroy
redirect_to cvs_path, :notice => "Your CV has been deleted"
end

Creating a resource that belongs_to another resource

Here are my relevant models:
class ListItem < ActiveRecord::Base
belongs_to :inventory_item
belongs_to :shopping_list
belongs_to :item
end
class ShoppingList < ActiveRecord::Base
has_many :list_items
belongs_to :user, :foreign_key => :user_id
end
class InventoryItem < ActiveRecord::Base
belongs_to :item, :foreign_key => :item_id
belongs_to :vendor
has_many :list_items
end
I want to have a button to create ListItems that belong to a user specified list that they own. The new ListItem also needs to be passed the respective :item_id and :inventory_item_id. Here's the relevant part of my current view:
<tr>
<% item.inventory_items.each do |product| %>
<td><%= button_to "#{product.price}",
{:controller => :list_items,
:action => 'create',
:id => #what goes here??,
:method => :create %></td>
<% end %>
</tr>
And my ListItems controller create method:
def create
ListItem.create
flash[:success] = "List Item Added."
redirect_to search_results_path(params[:search])
end
Clearly my create method isn't all that useful right now because it just creates a ListItem with no attributes other than :id. What's the best way to pass the appropriate parameters to my controller? Any help is much appreciated! Thanks in advance.
After doing a bunch of snooping around SO etc. I think the best way to accomplish this is to use a form with hidden fields, as below:
<%= form_tag("/list_items", method: "post") do %>
<%= hidden_field_tag(:item_id, item.id) %>
<%= hidden_field_tag(:inventory_item_id, product.id) %>
<%= hidden_field_tag(:shopping_list_id, ShoppingList.first.id) %>
<%= submit_tag("#{product.price}") %>
This is working well for me and is cleaner in this instance than using a button_to.

Destroy action on nested resource

Im trying to add a destroy button on my nested resource and getting this error: No route matches [DELETE] "/users/1/2/4/5/holidays/7"
Heres the relevant parts of my view,routes, models, & controllers:
<% #user.holidays.each do |h| %>
<td><%= h.name %></td>
<td><%= h.date %></td>
<td>
<%= button_to('Destroy', user_holiday_path(#user.holidays), :method => 'delete', :class => 'btn btn-large btn-primary') %>
</td>
<% end %>
Routes
resources :users do
resources :interests
resources :holidays
end
Models
class User < ActiveRecord::Base
has_many :holidays, :through => :user_holidays
end
class UserHoliday < ActiveRecord::Base
attr_accessible :holiday_id, :user_id
belongs_to :user
belongs_to :holiday
end
class Holiday < ActiveRecord::Base
attr_accessible :name, :date
has_many :user_holidays
has_many :users, :through => :user_holidays
end
Controller
class HolidaysController < ApplicationController
def index
#user_holidays = Holiday.find(params[:user_id])
#holidays = #user_holidays.holidays
end
def new
end
def show
#holiday = Holiday.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #holiday }
end
end
def destroy
#holiday = Holiday.find(params[:id])
#holiday.destroy
end
end
Thanks!!!
Change this :
<%= button_to('Destroy', user_holiday_path(#user.holidays), :method => 'delete', :class => 'btn btn-large btn-primary') %>
to this:
<%= button_to('Destroy', user_holiday_path(h), :method => 'delete', :class => 'btn btn-large btn-primary') %>
Update
Change your destroy action from :
#holiday = Holiday.find(params[:id]) to
#user_holiday = UserHoliday.find(params[:id])
and in your view:
change
<% #user.holidays.each do |h| %>
to
<% #user.user_holidays.each do |h| %>
Your associations need some correction and should be as follows:
user has_many user_holidays
user_holiday has_one holiday
user_holidays belongs_to user
You can access name and holiday via your h object:
h.holiday.name
h.holiday.date

Deleting just a join table record in Ruby on Rails

I have the following simple models:
class Event < ActiveRecord::Base
has_many :participations
has_many :users, :through => :participations
end
class Participation < ActiveRecord::Base
belongs_to :event
belongs_to :user
end
class User < ActiveRecord::Base
has_many :participations
has_many :events, :through => :participations
end
What I would like to do in my view is, dependant on the current users role, delete either an event and its participation record, or just a participation record on its own.
I currently have
<%= link_to 'Delete event', event, :confirm => 'Are you sure?',
:method => :delete %>
which deletes both event, and its participation. Do I need another action? or can hijack the destroy action of Event? What would it look like?
Thanks
Well, a hack could be something like this, in a view helper:
def link_to_delete_event( event, participation = nil )
final_path = participation.nil? ? event_path( event ) : event_path( :id => event, :participation_id => participation )
link_to 'Delete event', final_path, :confirm => 'Are you sure?', :method => :delete
end
And in your view you'd use link_to_delete_event( event ) to delete an event alone and link_to_delete_event( event, participation ) to delete the participation. Your controller could be something like this:
def destroy
#event = Event.find(params[:id])
unless params[:participation_id].blank?
#event.destroy
else
#event.participations.find( params[:participation_id] ).destroy
end
redirect_to somewhere_path
end
EDIT
To make it less of a hack you should create a nested resource for participations under events:
map.resources :events do |events|
events.resources :participations
end
And then you'll have to create a ParticipationsController, which could look like this:
class ParticipationsController < ApplicationController
before_filter :load_event
def destroy
#participation = #event.participations.find( params[:id] )
#participation.destroy
redirect_to( event_path( #event ) )
end
protected
def load_event
#event = Event.find( params[:event_id] )
end
end
And the link_to helper would change to this:
def link_to_delete_event( event, participation = nil )
if participation
link_to 'Remove participation', event_participation_path( event, participation ), :method => :delete
else
link_to 'Delete event', event_path( event ), :confirm => 'Are you sure?', :method => :delete
end
end

Resources