ActiveAdmin - Pass locals to form - ruby-on-rails-3

In my photos.rb file I have:
ActiveAdmin.register Photo do
form :partial => 'admin/forms/photo', :locals => { :events => Event.all }
end
In my _photo.html.erb file I want to be able to access the value of events, but it doesn't seem to be detectable. How can I do this?
As requested in a comment, here is my form:
<% if events.any? %>
<%= form_for [:admin, #photo], :validate => true do |f| %>
<!-- insert a bunch of standard field divs here -->
<div class="actions" style="margin-top: 20px">
<% if #photo.new_record? %>
<%= f.submit 'Create photo' %>
<% else %>
<%= f.submit 'Update photo' %>
<% end %>
</div>
<% end %>
<% else %>
<div style="font-size: 14px">
You cannot add photos until you have added at least one event.
</div>
<% end %>
The error message I am getting is around the events.any? line:
Completed 500 Internal Server Error in 108ms
ActionView::Template::Error (undefined local variable or method `events' for #<#<Class:0x007fdb8e841b80>:0x007fdb8a93e7a8>)

form do |f|
f.render partial: 'admin/forms/photo', locals: { f: f, events: Event.all }
end
Note that you will need to remove form_for, semantic_form_for, active_admin_form_for etc from your partial, since it will be covered by the form do part in the admin/photos.rb, otherwise there will be two nested forms.
Example partial:
# app/views/admin/forms/_photo.html.arb
if events.any?
f.inputs do
f.input :title, label: 'Etc'
f.input :file
end
f.actions
else
f.div 'You cannot add photos until you have added at least one event.',
style: 'font-size: 14px'
end

form do |f|
render partial: 'admin/forms/photo', locals: { value: 'random_data' }
end
You can use f.render or just render.
Note that partial: is required to send locals to the form
Example Partial
#app/views/admin/forms/_photo.html.arb
active_admin_form_for [:admin, resource] do |f|
f.semantic_errors *f.object.errors.keys
f.inputs do
f.input :name
f.input :random if (value == 'random_data')
end
f.actions
end

another thought on this, if you want to check only if there are any Events in db you can make any call directly on Class:
<% if Event.any? %>
do this
<% else %>
do that
<% end %>
without sending variables to partial, the above code result in:
2.0.0p0 :004 > Event.any?
(0.6ms) SELECT COUNT(*) FROM "events"
=> true
and leave the ActiveAdmin partial without locals:
ActiveAdmin.register Photo do
form :partial => 'admin/forms/photo'
end

Related

undefined method `model_name' in a partial rendered by different controller

I'm trying to render this form:
<form class="form-inline">
<%= simple_form_for #prospect,
:url => url_for(:action => 'create', :controller => 'prospects'),
:method => 'post' do |f| %>
<%= f.error_notification %>
<%= f.input :name, placeholder: 'Name', label: false %>
<%= f.input :email, placeholder: 'Email', label: false %>
<%= f.input :interests, placeholder: 'Tell us what you were searching for', label: false, value: params[:search] %>
<%= f.error :base %>
<%= f.button :submit, "Submit", :class=> "btn" %>
<% end %>
Using this partial:
<%= render partial: 'prospects/novideo_capture' %>
The partial is in a view controlled by Videos#index controller, and I keep getting this error: 'undefined method `model_name' for NilClass:Class'
This is my prospects controller:
class ProspectsController < ApplicationController
def index
#prospects = Prospect.all
end
def new
#prospect = Prospect.new
end
def create
#prospect = Prospect.new(params[:prospect])
if #prospect.save
render "thanks_for_interest"
else
render "novideo_capture"
end
end
I'm not sure what I'm going wrong, although I'm pretty sure it's a simple solution. I've seen a lot of similar questions around SO and tried all their answers, but none of them seem to work for this situation.
Thanks for any help...
EDIT: Adding
#prospect = Prospect.new
to the videos index controller stops the error occurring, but I don't feel it's the right way to do this. It also doesn't actually make the form use the prospects controller.
EDIT2: I now have the partial rendering correctly (I think), and my videos#index calls the partial like this:
<%= render partial: 'prospects/novideo_capture', :prospect => #prospect %>
Then simple_form in the partial looks like this:
<form class="form-inline">
<%= simple_form_for :prospect,
:url => url_for(:action => 'create', :controller => 'prospects'),
:method => 'post' do |f| %>
...
<% end %>
However it's not actually submitting the form with the prospects controller. Any ideas why?
Check your markup. You're wrapping a simple_form inside another form. Since the first form tag has no action associated with it (<form class="form-inline">), that form will submit against the current URL, which is the video#index.
You're going to want something like this:
<%= simple_form_for :prospect, :url => etc, :method => 'post', :class => "form-inline" do |f|
...
<% end %>
Losing the leading (redundant) form-inline form tag and you'll be fine.

How to update an attribute ':what_cause' of model user using group of radio button in rails3

I want to update an attribute ':what_cause' of model user on a page which is in a session. User clicks on one of the 3 radio buttons and corresponding value should be transferred to a method which updates it.
I wrote following code-
<%= form_for :user do |f| %>
<label>Pratham</label>
<%= f.radio_button :what_cause, "pratham" %>
<label>Kali</label>
<%= f.radio_button :what_cause, "kali" %>
<label>Akshaya</label>
<%= f.radio_button :what_cause, "akshaya" %>
<%= f.submit "Save", :controller => "users_controller", :action => "change_cause", :method => "put" %>
<% end %>
And here is the code for updation in change_cause method of users_controller.rb-
def change_cause
if params[:radio_button] == "pratham"
#user.update_attribute(:what_cause, "pratham")
end
if params[:radio_button] == "kali"
#user.update_attribute(:what_cause, "kali")
end
if params[:radio_button] == "akshaya"
#user.update_attribute(:what_cause, "akshaya")
end
end
But it is not working. Please enlighten me. I am a newbie in RAILS!!!
def change_cause
#user.update_attribute(:what_cause, params[:user][:what_cause])
end

Rails 3: Using a submit button to update a model attribute

I have a user model which contains an "email switch" column with a boolean value. I'd like to create a button in my view which allows the user to turn "on" and "off" their emails. I can't get the submit button to update the value in the User model.
<%= form_for :user do |f| %>
<label>On</label>
<%= f.radio_button :email_switch, true %>
<label>Off</label>
<%= f.radio_button :email_switch, false %>
<%= f.submit "Save", :controller => "dashboard_emails", :action => "update", :method => "put" %>
<% end %>
class DashboardEmailsController < ApplicationController
before_filter :require_user
def index
end
def update
end
private
def require_user
#user = #logged_in_user
end
class User
field :email_switch, type: Boolean, default: false
end
You need to pass the arguments to form_for not to the f.submit call. If you have a persisted user assigned to #user you should be able to do:
<%= form_for #user do |f| %>
<label>On</label>
<%= f.radio_button :email_switch, true %>
<label>Off</label>
<%= f.radio_button :email_switch, false %>
<%= f.submit "Save" %>
<% end %>
Of course you need resources :users in your config/routes.rb to get this working. This should then send a PUT request to /users/47, which in turn fires the #update action of your UsersController

Does a Rails plugin exist to build a show page (like a formbuilder)

I'm looking for a Rails plugin providing a builder for show.html.erb pages.
For example, with SimpleForm, an new.html.erb page might look like this :
<%= simple_form_for(#user, :url => user_registration_path, :html => ... }) do |f| %>
<%= f.input :email, :required => true %>
<%= f.input :password, :required => true %>
<%= f.input :password_confirmation, :required => true %>
...
<% end %>
But I was not able to find an equivalent for just displaying fields.
A generated show.html.erb page looks like :
<p>
<b>Email:</b>
<%= #user.email %>
</p>
...
But I'd like something like :
<%= simple_display_for(#user, :html => ... }) do |d| %>
<%= d.output :email %>
<%= d.output :name %>
...
<% end %>
Does this kind of builder exist?
Thanks
EDIT : If the builder use Twitter Bootstrap, that's even better :)
I don't know of any gems, but here is a simple example of how to build this feature yourself, which you can expand on:
lib/simple_output.rb
class SimpleOutput
def initialize(resource)
#resource = resource
end
def output(attribute)
#resource.send attribute
end
end
config/initializers/simple_output.rb
require_dependency 'lib/simple_output'
helpers/simple_output_helper.rb
module SimpleOutputHelper
def simple_output_for(resource, options={}, &block)
content_tag :div, yield(SimpleOutput.new(resource)), options[:html] || {}
end
end
users/show.html.erb
<%= simple_output_for(#user, html: { style: "background-color: #dedede" }) do |r| %>
<%= r.output :name %>
<%= r.output :email %>
<% end %>
Now, obviously this is just a very simple example, but hopefully it will get you started on the right track. Look at the simple_form source to see how they organize their code, and how they "typecast" fields. The simple_form codebase is very clean and easy-to-follow Ruby, and is a great example of what a gem should look like.

How to access attributes in a partial of a nested rails form?

I want to use the boolean attribute is_white from my inner_object to switch between html code in the the partial _inner_object_form_fields. This is my attempt.
<%= form_for #outer_object do |f| %>
<%= f.fields_for :inner_object do |builder| %>
<%= render :partial => "inner_object_form_fields", :locals => { :f => builder } %>
<% end %>
<% end %>
This is my attempt of the partial _inner_object_form_fields.
<% if f.is_white == true %>
<%= f.label(:name, "White") %>
<% else %>
<%= f.label(:name, "Black") %>
<% end %>
This is the migration file of InnerObjects.
class InnerObjects < ActiveRecord::Migration
def self.up
create_table :inner_objects do |t|
t.string "name"
t.boolean "is_white", :default => true
t.timestamps
end
end
def self.down
drop_table :inner_objects
end
end
I found a similar question but could not retrieve an answer for me.
The question is: How can access the attribut is_white? My example does NOT work.
Try
<% if f.object.is_white == true %>
Seem to remember you could access the object this way (not 100% sure though ;)
Is it because f.is_white is based on a blank object in the partial? Try
<%= form_for #outer_object do |f| %>
<%= f.fields_for f.inner_object do |builder| %>
<%= render :partial => "inner_object_form_fields", :locals => { :f => builder } %>
<% end %>
<% end %>
That way it's referencing the attached object and any state you've created.
Even one step further would be to do something like this:
<%= f.fields_for f.inner_object do |builder| %>
<%= render :partial => "inner_object_form_fields", :locals => { :f => builder, :inner_object => builder.object } %>
<% end %>
Then you can do.
<% if inner_object.is_white == true %>
This way your partials code looks a little cleaner.