I am using ActiveAdmin gem for admin console in ROR application. In my ActiveAdmin model-FeaturedEvent i have declared form for creating Featured event. FeaturedEvent model as a image field so i tried writing it. but it says NoMethodError in Admin::FeaturedEvents#new undefined method `new' for nil:NilClass. Following is my ActiveAdmin Model:
ActiveAdmin.register FeaturedEvent do
permit_params do
permitted = [:name, :location, :start_time, :description,:image,:phone, :email, :event_url, :active, :free, :image, :s3_credentials]
permitted << :other if params[:action] == 'create'
permitted
end
controller do
def create
byebug
#featuredevent = Event.new(permitted_params[:featuredevent])
if #featuredevent.save
redirect_to '/admin/featured_events#index'
else
flash[:message] = 'Error in creating image.'
end
end
def event_params
params.require(:event).permit(:name, :location, :start_time, :description,:image,:phone, :email, :event_url, :active, :free, :image, :s3_credentials)
end
end
form do |f|
inputs 'Create Private Events' do
input :image
end
actions do
button_to 'Create', featured_speakers_path(:featuredevent), method: :post
#link_to 'Create', {:controller => 'events', :action => 'create'}, {:method => :post }
end
end
end
Error in browser on navigating to create featured event:
**NoMethodError in Admin::FeaturedEvents#new**
undefined method `dirty?' for nil:NilClass
Ok i got it. Paperclip needs a different name for attachment declaration in FeaturedEvent model [I have other model in which image was used ]. Thank you Vishal
Related
In rails 3 we could use update_attributes as below
#customer.update_attributes(params[:customer], :as => :default)
or
#customer.update_attributes(params[:customer], :as => :admin)
and our attributes accessible would be defined as
attr_accessible :fname, :lname, :as => [:default, :admin]
attr_accessible :status, :as => [:admin]
But in rails 4, update_attributes does not accept second parameter. So how can I convert the above code to work in rails 4?
I tried something like this
#customer.update_attributes(customer_params)
private
def customer_params
params.require(:customer).permit(:fname, :lname, :status )
end
But I don't know how to pass the role in rails 4 while updating attributes. I can not do something like this.
#customer.update_attributes(customer_params, :as => :admin)
This is not allowed in rails 4. So how can I do similar thing in rails 4?
Have a look at strong parameters. The permitted attributes should be determined in the controller not the model
http://edgeguides.rubyonrails.org/action_controller_overview.html#strong-parameters
For example the controller would have
def customer_params
if current_user.admin?
params.require(:customer).permit(:fname, :lname, :status)
else
params.require(:customer).permit(:fname, :lname)
end
end
def update
#customer.update_attributes(customer_params)
...
end
Im using Rails 4 and I have a form within active admin that does not pre-populate or load relationship data into the edit form. If I dont define a form then the default that is loaded by active admin does, but it is shows the object and not the object.name for example so I have set out to edit it.
Here is what I have
form do |c|
c.semantic_errors *c.object.errors.keys
c.inputs "Event" do
c.input :title
c.input :date, :as => :datetime_picker, :local => true
c.input :description
end
c.inputs "Training Request" do
c.inputs :for => [:training_request, c.object.training_request || c.object.build_training_request] do |w|
list_of_training_requests = TrainingRequest.fulfilled.collect {|t| t.host.name }
w.input :id, as: :select, :collection => list_of_training_requests
end
end
c.inputs "Trainer" do
c.inputs :for => [:trainer, c.object.trainer || c.object.build_trainer] do |x|
list_of_trainers = Trainer.qualified.collect {|t| t.name }
x.input :id, as: :select, :collection => list_of_trainers
end
end
c.actions
end
The form loads without any errors and does list data just not what is set the in the database e.g.
If anyone can point me in the right direction it would be very much appreciated.
If the only problem with the original forms is that it just displays the object instead of name you could overwrite to_s in your models. For example:
class Trainer < ActiveRecord::Base
def to_s
name
end
end
Then when you call an instance of Trainer it should display the name property.
I have the following controller
class Dashboard::AvailabilitiesController < Dashboard::ApplicationController
def index
end
def new
end
def create
end
def destroy
end
end
with this model:
class Availability
include Mongoid::Document
include Mongoid::Timestamps
field :class_date, type: DateTime
belongs_to :kid
validates_uniqueness_of :class_date, :scope => [:class_date, :kid_id]
end
and this route:
namespace :dashboard do
resources :kids do
resources :availabilities
end
end
on my view, I have the following form:
= form_tag dashboard_kid_availabilities_url(current_kid), :method => 'post', :multipart => true do
.form-group
= datetime_select :class_date, {:start_year => Time.now.year, :order => [:day, :month, :year], :discard_minute => true}
.form-group
= submit_tag _('Save'), class: 'btn btn-blabloo btn-xs'
But I'm getting "uninitialized constant Dashboard::AvailabilitiesController" and I don't understand why. Also, I can remove the minutes selector of the forme using the discard_minute => true.
Any Idea please.
Thanks in advance
THe controller name should be within module Dashboard
module Dashboard
class AvailabilitiesController < ApplicationController
def index
end
def new
end
def create
end
def destroy
end
end
end
Another option is, probably, class Dashboard::AvailabilitiesController < ApplicationController.
Also make sure, that controller in under /controllers/dashboard/avaliabilities_controller.rb
I am trying to send an email notification once a nested attribute form has been updated, but I keep bumping into this error, I think it because I am sending the email notification before council model has updated the object in the database thus am getting a nil for Property.councils.email, any help would be greatly appreciated.
Property Mailer
class PropertyMailer < ActionMailer::Base
default from: "myemail#gmail.com"
def welcome_email(property, tenants, councils)
#property = property
#tenants = tenants
#councils = property.councils
mail(:to => property.councils.first.email, subject: 'Here are your property details')
end
end
property.rb
class Property < ActiveRecord::Base
has_many :council_histories
accepts_nested_attributes_for :council_histories, :reject_if => :send_email
has_many :councils, through: :council_histories, :foreign_key => :council_id
accepts_nested_attributes_for :councils
def send_email
if council_histories.where(council_id_changed?)
PropertyMailer.welcome_email(self, tenants, councils).deliver
end
end
end
Update #
'Property/Build Controller' Nested controller, am using wicked wizard form gem, to build a multi-step form.
class Properties::BuildController < ApplicationController
include Wicked::Wizard
steps :tenant, :meter, :council, :confirmed
def show
#property = Property.find(params[:property_id])
#tenants = #property.tenants.new(params[:tenant_id])
#meter = #property.build_meter
#property.council_histories.build do |council_history|
#council = council_history.build_council
end
render_wizard
end
def update
#property = Property.find(params[:property_id])
params[:property][:status] = step.to_s
params[:property][:status] = 'active' if step == steps.last
#property.update_attributes(params[:property])
render_wizard #property
end
end
Form View
<%= simple_form_for #property, url: wizard_path, :method => 'put' do |f| %>
<%= f.simple_fields_for :council_histories do |builder| %>
<%= builder.input :property_id, as: :hidden, input_html: { value: #property.id } %>
<%= builder.input :council_id, :collection => Council.all %>
<%= builder.submit %>
<% end %>
<% end %>
As Marek Lipka said, the property.councils most likely returns an empty hash, however that's only part of the story. I believe the issue is in your Property model, with this line:
has_many :council_histories
accepts_nested_attributes_for :council_histories, :reject_if => :send_email
^^
This is the problem here
Your original hypothesis is correct, I believe are you attempting to send the email before the :councils relationship has a chance to populate. The :reject_if method is used to, as the name implies, throw out the data in certain circumstances (I never use it myself so can't think of any good examples, but I'm sure there are plenty). Check here for more info.
Do you absolutely need the email to be sent BEFORE the object is persisted? If not, maybe another alternative would to use one of the ActiveRecord::Callback methods, such as after_commit, like so:
class Property < ActiveRecord::Base
after_commit :send_email
# Remainder of model code....
Your property.councils call returns empty set.
I've used Virtual attributes in the past but I can't seem to get past this, and I know the answer is probably staring me in the face.
I have a model like so:
model Confirmation.rb
class Confirmation < ActiveRecord::Base
#attr_accessible :confirmation, :confirmation_token
#attr_accessible :confirmation_token
def confirmation_token
confirmation.confirmation_token if confirmation
end
def confirmation_token=(token)
self.confirmation = Booking.find_by_confirmation_token(token)
end
end
Your average scaffold controller for
confirmations_controller.rb
def new
#confirmation = Confirmation.new(:confirmation_token => params[:confirmation_token])
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #confirmation }
end
end
new.html.erb
<h1>New confirmation</h1>
<% form_for(#confirmation) do |f| %>
<%= f.error_messages %>
<%= f.hidden_field :confirmation_token %>
...
routes.rb
map.confirmation "confirmation/:confirmation_token", :controller => "confirmations", :action => "new"
map.resources :confirmations
error
undefined method `confirmation=' for #
In the console Booking.find_by_confirmation_token(token) with a given token works perfectly fine.
Any ideas? suggestions?
What you really need is attr_accessor :confirmation. There's a difference between attr_accessible and attr_accessor.
attr_accessor :confirmation
is same as
def confirmation
#confirmation
end
def confirmation=(value)
#confirmation = value
end
Now since it's such a common pattern ruby introduced helper methods for that.
Attr_accesible on the other hand is rails method, which marks that certain fields can be mass updated.
I think it should be either:
def confirmation_token=(token)
#confirmation = Booking.find_by_confirmation_token(token)
end
Or you should uncomment attr_accessible :confirmation or define #confirmation and #confirmation=.
class Confirmation < ActiveRecord::Base
belongs_to :bookings
#attr_accessible :confirmation, :confirmation_token
#attr_accessible :confirmation
def confirmation_token
#confirmation.confirmation_token if #confirmation
end
def confirmation_token=(token)
#confirmation = Booking.find_by_confirmation_token(token)
end
end
this worked... however just uncovering the attr_accessible :confirmation, did not. self.confirmation still returned undefined method...