Overriding a new controller without 'new!' does not display ActiveAdmin layout. But then when I added 'new!' nested 'synchronization' form is not appearing although I did '#resource.build_synchronization'. Not so sure what I'm doing wrong here.
case #1 (ActiveAdmin layout is gone)
ActiveAdmin.register Resource do
controller do
# This code is evaluated within the controller class
def new
#resource = Resource.new
#resource.build_synchronization
end
end
end
case #2 (nested form synchronization does not appear)
ActiveAdmin.register Resource do
controller do
# This code is evaluated within the controller class
def new
#resource = Resource.new
#resource.build_synchronization
new!
end
end
end
views\admin\resources\new.html.erb
<%= semantic_form_for [:admin, #resource] do |form| %>
<%= form.inputs "Resource", :id => "resource" do %>
<%= form.input :name %>
<%= form.semantic_fields_for :synchronization do |sync| %>
<% sync.inputs :name => "Synchronization", :id => "synchronization" do %>
<%= sync.input :start_datetime, :as => :datetime %>
<%= sync.input :repeat_interval, :as => :radio, :collection => #intervals %>
<%= sync.input :repeat_type, :as => :select, :collection => ["Manual", "Automatic"] %>
<% end %>
<% end %>
<% end %>
<%= form.buttons %>
<% end %>
<% end %>
models:
class Resource < ActiveRecord::Base
has_one :synchronization
accepts_nested_attributes_for :synchronization
end
class Synchronization < ActiveRecord::Base
belongs_to :resource
has_many :mappings
accepts_nested_attributes_for :mappings
#validates_presence_of :start_datetime
end
For CRUD actions active admin don't use standart layout
lib/active_admin/resource_controller.rb
# Determine which layout to use.
#
# 1. If we're rendering a standard Active Admin action, we want layout(false)
# because these actions are subclasses of the Base page (which implementes
# all the required layout code)
# 2. If we're rendering a custom action, we'll use the active_admin layout so
# that users can render any template inside Active Admin.
def determine_active_admin_layout
ACTIVE_ADMIN_ACTIONS.include?(params[:action].to_sym) ? false : 'active_admin'
end
You can define layout manually
controller do
layout 'active_admin', :only => [:new]
end
You need to put the form.semantic_fields_for statement inside a form.inputs block.
Also, I would not put form.buttons inside neither the form.semantic_fields_for block nor a form.inputs block. It should be a direct child under the semantic_form_for block (this is not what is causing your problem, but just the location where you would normally put this).
Related
I'm fairly new to rails, though I've made some basic apps and read several tutorials, this is the first time I've delved into nested attributes inside forms and the use of fields_for.
I've searched trough many similar questions and have read the documentation on fields_for, however my form doesn't seem to save whenever I use fields_for inside my form. I've tested without the fields_for and saves as it should (without saving to the nested DB, obviously).
What I'm trying to do is a simple Event registration, which in turn has some attributes and a date in a separate model.
I've tried with and without validations, many different things inside the strong parameters
Here is my Event models:
class Event < ApplicationRecord
has_many :eventdates, dependent: :destroy
accepts_nested_attributes_for :eventdates
validates :name, :description, :city, :street, :postal_code, presence: true
end
The Eventdate model:
class Eventdate < ApplicationRecord
belongs_to :event
validates :date, :start_hour, :finish_hour, :event_id, presence: true
end
The Event controller:
class EventsController < ApplicationController
def new
#event = Event.new
#event.eventdates.build
end
def create
#event = Event.new(event_params)
if #event.save
redirect_to root_url
else
render "static_pages/home"
end
end
private
def event_params
params.require(:event).permit(:name, :description, :street, :city, :postal_code, :address_number, :additional_info,
eventdates_attributes: [:id, :date, :start_hour, :finish_hour, :event_id])
end
And the form:
<%= form_for(#event, url: events_path) do |f| %>
<p>
<%= f.label :nombre %>
<%= f.text_field :name %>
</p>
<div>
<%= f.fields_for :eventdates do |eventdate_fields| %>
<%= eventdate_fields.label :fecha %>
<%= eventdate_fields.date_field :date %>
<%= eventdate_fields.label :hora_de_inicio %>
<%= eventdate_fields.time_field :start_hour %>
<%= eventdate_fields.label :hora_de_termino %>
<%= eventdate_fields.time_field :finish_hour %>
<% end %>
</div>
<p>
<%= f.label :infomación_adicional %>
<%= f.text_area :additional_info %>
</p>
<p>
<%= f.submit "Crear evento" %>
</p>
<% end %>
I'm pretty sure this is a very simple form, but somehow refuses to save at all into the database.
In eventdate.rb model, append optional: true to this line: belongs_to :event
class Eventdate < ApplicationRecord
belongs_to :event, optional: true
validates :date, :start_hour, :finish_hour, :event_id, presence: true
end
Because Rails will create eventdates first, then create event and links to those evendates (by updating all event_id in these evendates). But when creating eventdates, column event_id is nil and eventdates cannot be saved.
I'm trying to embedded mail_form into my home page.
The 'contacts#new' is rendered on 'static_pages#home' so I instantiate #contact in StaticPagesController's home action to avoid the "First argument in form cannot contain nil or be empty" error.
But I now I get wrong number of arguments (0 for 1..2) errors instead.
I see this behaviour since I updated my ruby to 2.2.2.
Do you think this error is caused by new specification on Ruby, or it is just my simple code error?
static_pages_controller
class StaticPagesController < ApplicationController
def home
#contact = Contact.new
end
end
views/static_pages/home.html.erb
<section id="contact">
<%= render template: 'contacts/new' %>
</section>
contacts_controller
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
#contact.request = request
if #contact.deliver
flash.now[:notice] = "Thank you for your message. We will contact you soon!"
else
flash.now[:error] = "Cannot send message."
render 'new'
end
end
private
def contact_params
params.require(:contact).permit(:name, :email, :message)
end
end
views/contacts/new.html.erb
<%= form_for(#contact) do |f| %>
...
<% end %>
Logs
Processing by StaticPagesController#home as HTML
Rendered contacts/new.html.erb (23.5ms)
Rendered static_pages/home.html.erb within layouts/application (238.2ms)
Completed 500 Internal Server Error in 278ms
ArgumentError (wrong number of arguments (0 for 1..2)):
app/views/contacts/new.html.erb:28:in `block in_app_views_contacts_new_html_erb___4238619170782302276_70113984753480'
I update my version of 'byebug' to '4.0.1' and 'Web-console' to '2.1.2', then it shows where was the error. It was actually really stupid ...
Error:
<%= form_for(#contact) do |f| %>
<%= t.email_field ... %>
...
<% end %>
Correct:
<%= form_for(#contact) do |f| %>
<%= f.email_field ... %>
...
<% end %>
I'm trying to figure out how to search multiple models with Ransack. The goal is to have the search form in my shared header. I'm using a combination of their documentation, an old rails-cast, SO questions, and some code a friend shared with me. Right now I think it works, although I'm not sure because I can't get the results to show on my index page.
First, I created a search controller:
class SearchController < ApplicationController
def index
q = params[:q]
#items = Item.search(name_cont: q).result
#booths = Booth.search(name_cont: q).result
#users = User.search(name_cont: q).result
end
end
Next, I put this code in the header partial (views/layouts/_header.html.erb):
<%= form_tag search_path, method: :get do %>
<%= text_field_tag :q, nil %>
<% end %>
I added a route:
get "search" => "search#index"
My index.html.erb for the Search controller is empty and I suspect that is the problem, but I'm not sure what to place there. When I try something like:
<%= #items %>
<%= #users %>
<%= #booths %>
This is the output I get when I execute a search:
#<Item::ActiveRecord_Relation:0x007fee61a1ba10> #<User::ActiveRecord_Relation:0x007fee61a32d28> #<Booth::ActiveRecord_Relation:0x007fee61a20790>
Can someone please guide me on what the solution might be? I'm not sure if it's an index view problem, routing problem, or something else. On all of the tutorials the search field and results are only for one model so I'm a little confused on how to pull this off across multiple models.
Thanks!
The output you are getting is correct. Each of those variables contains an ActiveRecord_Relation object which can be treated like an array. Normally you'd do something like:
<% #items.each do |item| %>
<%= item.name %> # or whatever
<% end %>
<% #users.each do |user| %>
# and so on
Alternatively, you could combine your results #results = #items + #booths + #users and then:
<% #results.each do |result| %>
# display the result
<% end %>
Error: "Param is missing or the value is empty :child"
I've nested objects (child controler & viewers are in Parent folder). On parent detail page I list all children in a table. Other methods like edit, update, new work. But I want to have a link with my method 'graduate' that enables to change child attribute graduate_date on the parent page. I attempt to do it by changing date of graduation for Time.now in Child controller#graduate action
class ParentsController
def show
#parent = Parent.find params[:id]
#children = #parent.children
end
-- Parent view --
<% #children.each do |child| %>
<tr>
<td><%= child.name %>
<% if child.graduated? %>
<td> graduated </td>
<% else %>
<td><%= link_to 'graduate now', graduate_parent_child_path(#parent, child) %></td>
<% end %>
</tr>
<% end %>
-- models --
Parent: has_many
Child: belongs_to
-- child controller --
def graduate
#parent = Parent.find params[:parent_id] ==> parent_id & id are correct
#child = Child.find params[:id]
#child.update_attribute(:graduation_date, Time.now.strftime(%m%d%Y)) ==> here does not updates!!!
end
-- routes.rb --
resources :parents do
resources children, controller: parent/children do
member { match :graduate, via [get, patch] } ==> rails forces me to use get
end
end
Rais forces me to use get in routes. I'm connected to controller, 2 first lines of 'graduate' work correctly but attributes are not updated but graduated_date has assigned nil instead.
In your ParentsController you set #child, but in your view you look for #children
I have a form_for that has a fields_for for a double object form creation. The second object is attachments that has a paperclip (ruby gem) attribute for adding photos attributed to the first object. The box model is being created, but the attachment model is not as far as I can tell. One of my questions is where the multipart => true needs to go, the form_for, fields_for, or both?
Edit: it seems that the box_id cannot be passed through as a param because the box hasn't been created yet. So how do I make the attachment attributed to the box in the controller? I thought
#box.attachments.build(params)
would make the correct attribution, but that doesn't work.
Do I need to user nested attributes here?
Here is the console log:
Processing by BoxesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"0vka+nZDc56OdISMctWoJjY8CH+TR20PHBl8oVglD5A=", "box"=>{"user_id"=>"45", "name"=>"asdfasdf", "origin"=>"asdfasdf", "description"=>"asdfasdf"}, "attachment"=>{"box_id"=>"", "screen_shot"=>#<ActionDispatch::Http::UploadedFile:0x007fc3d8202990 #tempfile=#<Tempfile:/tmp/RackMultipart20140521-11119-37nj3s>, #original_filename="P5110017.JPG", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"attachment[screen_shot]\"; filename=\"P5110017.JPG\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Share the Love!"}
Note that the box_id is blank, yet with the validation in the model I don't get any errors.
Here is my form code:
<%= form_for #box, :html => { :multipart => true } do |f| %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.label :name, "Name" %><br>
<%= f.text_field :name, autofocus: true %><br>
<%= f.label :origin, 'Website' %><br>
<%= f.text_field :origin %><br>
<%= f.label :description %><br>
<%= f.text_area :description, cols: "30", rows: "4" %>
<%= fields_for #attachment do |ff| %>
<%= ff.hidden_field :box_id, :value => #box.id %>
<%= ff.file_field :screen_shot, id:"attachment", :required => true %>
<% end %>
<%= f.submit "Create!" %>
<% end %>
Here is my controller:
class BoxesController < ApplicationController
def new
#box = Box.new
#attachment = Attachment.new
end
def create
#box = current_user.boxes.build(boxes_params)
#attachment = #box.attachments.build(attachment_params)
if #box.save
flash[:success] = "Box created"
redirect_to #box
else
flash[:error] = "There was an error"
redirect_to 'new'
end
end
def update
#box = Box.find(params[:id])
if #box.update_attributes(boxes_params)
flash[:success] = "Box updated"
redirect_to #box
else
render 'edit'
end
end
def destroy
#box = Box.find(params[:id])
#box.destroy
flash[:success] = "Box deleted."
redirect_to root_url
end
private
def boxes_params
params.require(:box).permit(:description, :name, :origin, :attachment)
end
def attachment_params
params.require(:attachment).permit(:screen_shot, :box_id)
end
end
And the box model:
class Box < ActiveRecord::Base
belongs_to :user
has_many :comments
has_many :attachments, :dependent => :destroy, :limit => 4
is_impressionable
validate :attachments_count_within_limit, :on => :create
validates :user_id, presence: true
validates_presence_of :name
validates_length_of :description, :maximum => 1000
Attachment model:
class Attachment < ActiveRecord::Base
belongs_to :box
has_attached_file :screen_shot, :styles => { :medium => "300x300>", :thumb => "100x100>" }
validates_attachment_content_type :screen_shot, :content_type => /\Aimage\/.*\Z/
validates :box_id, presence: true
end
I had also tried changing the box_controller to create the attachment via
#attachment = Attachment.new(attachment_params)
but that still did not work.
Try printing out #box.id in your view and see if it contains the required id and also send your box_id along with :screenshot
def attachment_params
params.require(:attachment).permit(:box_id, :screen_shot)
end