Trying to get nested objects to be given parent ids - ruby

Alright, So I have days, tracks, and events. When I create a track, it is given the proper day_id along with its own track_id . When I try to create an event, I want it to be given the appropriate day_id and/or track_id.
So when I pull up a day it should only show the tracks and events that as associated with the day. An event should exist in a track, which exists in a day.
So, this is basically a calendar that shows a daily schedule of different tracks, and the events within the tracks.
Also, my events table in my db has a track_id and a day_id.
Here is my routes.rb
resources :days do
resources :tracks do
resources :events
end
end
My new/create methods from my events_controller.rb
def new
#day = Day.find(params[:day_id])
#track = Track.find(params[:track_id])
#new_event = Event.new
end
def create
#day = Day.find(params[:day_id])
#track = Track.find(params[:track_id])
#events = #track.events
#new_event = Event.new(params.require(:event).permit(:name,:start_time, :end_time))
if #new_event.save
flash[:notice] = "Saved"
redirect_to #day
else
flash[:error] = "Error"
render :new
end
end
And here is where I am trying to create a new event in my events.new.html.erb
<%= form_for [#day, #track, #new_event] do |f| %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', placeholder: "Enter the event" %>
<%= f.label :start_time %>
<%= f.text_field :start_time, class: 'form-control', placeholder: "Enter a start time"%>
<%= f.label :end_time %>
<%=f.text_field :end_time, class: 'form-control', placeholder: "Enter a start time"%>
<%= f.submit "Save", class: 'btn btn-success' %>
<% end %>
Thanks for the help, I'm pretty sure I attached everything that was needed!

You should create the event from the track:
#new_event = #track.events.new
This will create an event with already the appropriate track_id inside.

However, this does work...
#new_event = #track.events.new(params.require(:event).permit(:name, :start_time, :end_time))

Related

Missing Params on Post in Rails?

I'm learning Ruby on Rails at the moment and we're making a blog app to learn about crud actions and such and I'm stuck on this create method in my controller not working as it does in the course. I'm having trouble the create method in this controller:
class ArticlesController < ApplicationController
def show
#article = Article.find(params[:id])
end
def index
#articles = Article.all
end
def new
end
def create
#article = Article.new(params.require(:article).permit(:title, :description))
#article.save
redirect_to #article
end
end
I get this error when trying to create an article:
ActionController::ParameterMissing in ArticlesController#create
param is missing or the value is empty: article
It seems to be getting hung up on the first line of the create method but I'm not sure why it doesn't think there's an article... Here's my new article view as well for further reference:
<h1>Create a new Article</h1>
<%= form_with scope: #article, url: articles_path, local: true do |f| %>
<p>
<%= f.label :title %><br/>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %><br/>
<%= f.text_area :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Check whether your parameters coming under hash with key article like this -
{"article"=>{params}}
Also initiate Article object in new action.
You can redefine the params to permit like this:
in controller new method create object
#article = Article.new
and in form HTML add one more option use method: "post"

Error trying to call a method on an object that belongs to another object

I have recs, which belong to a list, and lists, which have many recs. I am trying to figure out why I can't call my 'to_do' method below on the recs that belong to a list? This is in the 2nd row of view code. I'm getting the following error:
SQLite3::SQLException: near ")": syntax error: SELECT "recs".* FROM "recs" WHERE "recs"."list_id" = ? AND (done = 'false'))
Rec Model
class Rec < ActiveRecord::Base
belongs_to :list
scope :to_do, lambda {where("done = ?)", 'false')}
end
List model
class List < ActiveRecord::Base
has_many :recs
end
Controller
def index
#recs = Rec.to_do
#lists = List.all
#networks = Network.all
end
View
<% network.lists.eat_lists.each do |list| %>
<% if list.recs.to_do.present? %>
<%= list.name %></br>
<% list.recs.each do |rec| %>
<%= rec.name.split(',').first %>
<%= rec.notes %>
<%= rec.done %>
<%= link_to 'Done', marked_as_done_url(rec), method: :patch %></br>
<%= link_to 'Delete', rec, method: :delete %></br>
<% end %>
<% end %>
<% end %>
change your scope to this scope :to_do, lambda {where("done = ?", false)} or scope :to_do, lambda {where(done:false}, notice i have removed one closing bracket in string

Ajax and Ruby on Rails with local variable?

I really don't get how to use Ajax with Ruby on Rails. I must be missing something simple.
What I want to do is to ask the user to select a date, and then make a table of documents appear, but only with the selected date (Date is an attribute of Document).
My idea is to create a local variable witch is not in my database, store the selected date in it, and then create a loop in my view saying for example #document.where(:date = date).each...
In app/controllers/documents_controller.rb, I have :
class DocumentsController < ApplicationController
def information
#documents = Document.all
#date = params[:date]
respond_to do |format|
format.html # index.html.erb
format.js{}
format.json { render json: #documents}
end
end
end
And in app/views/documents/_information.js.erb, I have:
<%= form_tag(document, :remote => true) do %>
<%= label_tag(:date, "The selected date is:") %>
<%= text_field_tag(:date) %>
<%= submit_tag %>
<% end %>
In the end, I have a field where the user puts his date, but the submit button doesn't do anything.
What do I miss ?
As discussed you need to change the flow of your app.Lets go through steps one by one
a. create your input field where you are selecting your date field. You already have your form for that
<%= form_tag(you_path_for_information_method, :remote => true) do %>
<%= label_tag(:date, "The selected date is:") %>
<%= text_field_tag(:date) %>
<%= label_tag(:portfolio, "Add portfolio") %>
<%= text_field_tag(:portfolio) %>
<%= submit_tag %>
<% end %>
In controller
def information
#documents = Document.all
#date = params[:date]
#portfolio = Portfolio.find(params[:portfolio])
respond_to do |format|
format.js{}
end
end
In your information.js.erb you can have:
$("#some_id_of_parent").html("<%=j render partial: "your_partial", locals: {portfolio: #portfolio} %>")

How to call an `f.action` to a custom :delete callback in an Active Admin form

In order to remove (paperclip) images from my objects, I have a custom callback (and route) defined:
ActiveAdmin.register Camping do
#...
member_action :destroy_image, :method => :delete do
camping = Camping.find(params[:id])
camping.image.destroy
redirect_to({:action => :show}, :notice => "Image deleted")
end
end
This works as expected; trough a named route destroy_image_admin_camping => /admin/campings/:id/destroy_image.
The problem is that I cannot find how to add this to the form:
ActiveAdmin.register Camping do
form do |f|
f.inputs "Camping" do
f.input :name
f.input :image
f.action :delete_image, :url => destroy_image_admin_camping_path(#camping.id), :button_html => { :method => :delete }
f.input :description
end
f.actions
end
#...
end
More detailed: I don't know how to pass the "id of the current item we are editing" into destroy_image_admin_camping_path; #camping is nil, f.camping not defined and so I don't know how to pass the item in there.
Is this the right approach? I prefer this "ajax-ish" interface over a more common checkbox-that-deletes-images-on-update, but I am not sure if this will work at all.
There's a few questions here, I'll try to address them all.
How to access the "id of the current item we are editing"
You are pretty close in looking for f.camping. What you want is f.object, so:
destroy_image_admin_camping_path(f.object.id).
NOTE: f.object.id will be nil when it's a new form (as opposed to an edit form), you'll want to check for that with unless f.object.new_record?
"Is this the right approach?"
I'm not sure, really. To me it seems like making requests without actually saving the currently rendered form could create complications, but it might turn out to be a better interface. Anyway, if you want to do the checkbox-that-deletes-images-on-update, this should help you out: Rails Paperclip how to delete attachment?.
However, if you want the ajax-ish approach I think you'll want an <a> tag styled as a button. The problem with actually using a button is that you don't want to submit the form.
Here's an example:
f.inputs do
link_to 'Delete Image', delete_image_admin_camping_path(f.object.id), class: 'button', remote: true, method: :delete
end
remote: true will make it an ajax request and ActiveAdmin gives you a pretty reasonable button class for <a> tags. Updating the interface based on success / failure is left as an exercise to the reader.
Also, you'll probably want to use erb templates for this instead of the Active Admin DSL (see http://activeadmin.info/docs/5-forms.html at the bottom).
Like this:
# app/views/admin/campings/_form.html.erb
<%= semantic_form_for [:admin, #post] do |f| %>
<%= f.inputs do %>
<%= f.input :name %>
<%= f.input :image %>
<%# Actually, you might want to check for presence of the image, I don't know Paperclip well enough to demonstrate that though %>
<% unless f.object.new_record? %>
<%= image_tag f.object.image_url %>
<%= link_to 'Delete Image', delete_image_admin_camping_path(f.object.id), class: 'button', remote: true, method: :delete %>
<% end %>
...
<% end %>
<%= f.actions %>
<% end %>

How can I use do edit-in-place on three different models from a View for a model those three belong_to?

I would like to enable edit-in-place functionality in a View that displays values from different models:
This is what I use currently and it does NOT work, but would like some alternatives:
I have a model called Campaign. In the controller, I do the following to list, in order, the three Models that belong_to a Campaign:
<% #campaign_events = campaign_events %>
<% #campaign_events.each do |campaign_event| %>
<% model_name = campaign_event.class.name.tableize.singularize %>
<p>
<%= link_to campaign_event.title, send("#{model_name}_path", campaign_event) %>
<span class='model_name'>(<%= model_name.capitalize %>)</span>
<%= campaign_event.days %> Days
</p>
<% end %>
campaign_event is a campaign_helper defined as:
module CampaignsHelper
def campaign_events
return (#campaign.calls + #campaign.emails + #campaign.letters).sort{|a,b| a.days <=> b.days}
end
end
I want to be able to click on the numerical value for Days when looking at the view/campaign/show and edit the value for :days (in this case, displayed as campaign_event.days
I'm not really sure about it, but I'll try to help... I believe something like the following may work for you:
# calls controller
in_place_edit_for :call, :days
# emails controller
in_place_edit_for :email, :days
# letters controller
in_place_edit_for :letter, :days
# campaign view
<% #campaign_events = campaign_events %>
<% #campaign_events.each do |campaign_event| %>
<% controller_name = campaign_event.class.name.tableize %>
<% model_name = controller_name.singularize %>
<p>
<%= link_to campaign_event.title,
send("#{model_name}_path", campaign_event) %>
<span class='model_name'>(<%= model_name.capitalize %>)</span>
<%= in_place_editor_field model_name, :days, {},
:url => {
:controller => controller_name,
:action => 'set_#{model_name}_title',
:id => campaign_event.id} %> Days
</p>
<% end %>
There's somethings I don't know exactly how to do:
1) in_place_editor_field model_name
I believe this won't work, but I don't know how to pass the model_name.
2) :action => 'set_#{controller_name}_title'
Not sure about it also. Just doesn't look right.
Anyway, hope it helps you... and forgive me if this is completely stupid.

Resources