ActiveAdmin modify existing controller action - ruby-on-rails

In ActiveAdmin I am trying to edit instance variables in the show view. I have tried to do this with the following code per the ActiveAdmin docs:
#admin/job.rb
ActiveAdmin.register Job do
...
controller do
def show
#job = Job.find(params[:id])
#comment = Comment.new
#comments = #job.comments
end
end
...
This is resulting in a nilClass error when I try to use those variables in the ActiveAdmin show because they aren't really defined. Am I misunderstanding how the controller actions should be edited?

Try to use the show block not the show action in the controller:
https://github.com/activeadmin/activeadmin/blob/master/docs/6-show-pages.md#customize-the-show-page
ActiveAdmin.register Job do
show do |job|
attributes_table do
row :attributes_of_job
end
#you can also reach the comments like this: job.comments
active_admin_comments
end
end

Related

active admin how to render form on index page if object not created

I can't understand what I do wrong. My code won't work if subscription blank, but if I created it from rails c, all works fine...
# frozen_string_literal: true
ActiveAdmin.register Subscription do
actions :index
index do
result = Subscriptions::GetPricing.call(admin: current_admin)
if result.success?
render partial: 'subscription_form', locals: { amount: result.plan.amount }
else
flash[:alert] = result.message
render partial: 'subscription_errors'
end
end
end
Now i get: There are no Subscriptions yet. simple message.
And i want left all styles, nav panel, etc how it default, but in container should be store my code from partials.
If your intent is to display an input form if the table is unpopulated then try this:
controller do
def index
collection.size == 0 ? redirect_to(new_subscription_path) : super
end
end
I think what you are trying to do is a bit wrong. index do block is to render the view level mainly. If you want to override controller action you will have to do it like below -
controller do
def index
# your code here
end
end
Have a look at the documentation -
https://activeadmin.info/8-custom-actions.html
https://activeadmin.info/3-index-pages.html

rails render action with that's params

My route for pages in routes.rb
get ":slug", to: 'site#pages'
my actions in site_controller.rb
def pages
render #page.page_template
end
def about
end
def contact
end
def content
end
def local_news
end
def global_news
#newscasts = Newscast.published.paginate(page: params[:page], per_page: 5)
end
and it's my error :)
Not see global_news action my #newscasts parameter
You need to define #newscasts inside pages method
#newscasts = Newscast.published.paginate(page: params[:page], per_page: 5)
Or you can write this in your controller above your methods.
before_action :global_news, only: [:pages]
Before action will run your global_news methods before every action defined inside only: in your case you can write (:pages) you can mention as many methods you want. If you remove only then global_news will run before every method.
This cast an error because you are just rendering the global_news. With render you are not executing the controller action. So #newscast is never set.
You can either use a before filter as in the other answer or call the method manually, because I think you are doing something dynamically here, right?
for example
def pages
global_news
render #page.page_template
end

Ruby on rails - Template missing prob

I am having a hard time solving this problem because this is my first time to learn ruby on rail, i have a index.html.erb, new.html.erb, show.html.erb, edit.html.erb files. So when i go to localhost:3000/blogs/edit page the page that is showing is show.html.erb and when i delete the show.html.erb then access the edit.html.erb im having a template missing error. but when i access localhost:3000/blogs/new or just localhost:3000/blogs its working fine.So here's my code inside blogs_controller.rb
class BlogsController < ApplicationController
def index
#content_first = 'This 1' ;
#content_two = 'This 2' ;
end
def new
end
def create
end
def edit
end
def update
end
def show
end
def destroy
end
end
I think your problem is that you're trying to access /blogs/edit , and the route is probably /blogs/edit/:id. As in you need to provide the id of a blog object, so that you can edit it.
If you run
rake routes
You will be able to see your available routes.
Hope this helps =)

Rails NoMethodError undefined method `data' for nil:NilClass (Controller#update)

Edit: it turns out I made a very simple mistake and had a Template that was associated with a LocalTemplate id that no longer existed. If anyone has this problem and thinks that they somehow are unable to unable to associate the id of another model in their update action, make sure that you didn't accidentally delete the parent object causing that id to no longer exist!
The code below, while dramatically simplified did work for me.
I have a Template model in my rails app. It has a method "data" defined in it.
I am able to access this method in the create and show actions with #template.data, however when using the same #template.data in the update action of my controller I get a no method error because I am not showing the correct local template id to it. This line can be found in the model where it reads base_data = YAML.load(local_template.data)
I stored an id of the associated local_template when initially saving a new template, but how can I make sure I reference that id again in the update action so I do not get a no method error?
Here is a simplified version of the Template model and controller
Model:
class Template < ActiveRecord::Base
def data
base_data = YAML.load(local_template.data)
# couldn't pass the correct LocalTemplate here because
# the local_template_id I had in my Template model no
# longer existed. Changing the id to a LocalTemplate
# that did exist fixed the issue.
end
end
Controller:
class TemplatesController < ApplicationController
def index
#business = Business.find(params[:business_id])
#templates = #business.templates.all
end
def new
#business = Business.find(params[:business_id])
#local_templates = LocalTemplate.all
#template = #business.templates.build
end
def create
#business = Business.find(params[:business_id])
#local_templates = LocalTemplate.all
#template = #business.templates.build(template_params)
if #template.save
#template.data #works fine here
redirect_to business_url(#template.business_id)
else
render 'new'
end
end
def show
#business = Business.find(params[:business_id])
#template = #business.templates.find(params[:id])
#template.data #works fine here too
end
def edit
#business = Business.find(params[:business_id])
#local_templates = LocalTemplate.all
#template = #business.templates.find(params[:id])
end
def update
#business = Business.find(params[:business_id])
#template = #business.templates.find(params[:id])
if #template.update_attributes!(pass_template_params)
Api.new.update_template(#template.data.to_json) #this is where I had a problem
redirect_to business_url(#template.business_id)
else
render 'edit'
end
end
end
You are mixing a lot. There is a lot to refactor in your controller...
First of all, your TemplatesController should be about the template resources, but your controller looks more like a BusinessesController. In general your update action for example should look more like:
def update
#template = Template.find params[:id]
#template.attributes = template_params # though this should raise a NoMethodError, because you dind't define it; I'd prefer params[:template] if possible
if #template.save
redirect_to business_url(#template.business_id)
else
#local_templates = LocalTemplate.all
render 'edit'
end
end
Instantiating #business and #local_templates makes non sense, because you don't use it at all. Speed up your responses if you can! :)
Fixed that, there is no need for the overhead of a nested resource in update (as you did).
If saving #template fails for validation reasons, you better should load the business object late by:
#template.business
in your /templates/edit.html.erb partial. Then you also do not need a nested route to your edit action... You see, it cleans up a lot.
As a general guideline you should create as less as possible controller instance variables.
If you cleaned up your controller and views, debugging your data issue will be easier.
I assume:
local_template
in your Template model to be an associated LocalTemplate model object. So it should no issue to call that anywhere if you ensured the referenced object exists:
class Template < ActiveRecord::Base
def data
return if local_template.nil?
YAML.load(local_template.data)
end
end
or validate the existence of the local_template object. or even b
You should confirm #template is not nil, if #template is nil, you can't use data method.
1.9.3-p547 :024 > nil.data
NoMethodError: undefined method `data' for nil:NilClass
from (irb):24
from /Users/tap4fun/.rvm/rubies/ruby-1.9.3-p547/bin/irb:12:in `<main>'
And you should use update_attributes!, it can raise an exception if record is invalid.
You can do like this.
if #template
#template.update_attributes!(template_params)
#template.data
end

pass data from Rails to javascript in my case

My controller:
class SchoolController < ApplicationController
def index
...
end
def edit
#school=School.find_by_id params[:id]
end
def check_teachers
#teachers = #school.teachers
#How to show teachers' names and titles in a lightbox by javascript ?
end
end
As you see above, I have a check_teachers method, inside which I got a list of teachers objects. Each Teacher object has name and title attributes.
A button click on the view will trigger the check_teachers method get called:
I would like to show all teachers name and title in a lightbox. I think I would need javascript to implement this. But I don't know how can I pass all the teachers' data from Rails to javascript and show the data in a js implemented lightbox...
Anyone can provide any help on this?
you can do it with ajax. Simpliest way is to use FancyBox(jquery plugin, http://fancybox.net/home )
your button code should looks like
<a id="ajax_button" href="<%= url_for :controller => :school, :action =>:check_teachers, :id=>#school.id %>">Check teachers</a>
then add this javascript
$(document).bind('load', function() { $("#various3").fancybox({ajax:{type : "GET" } })
and your method controller action should looks like
def check_teachers
#school = School.find(params[:id])
#teachers = #school.teachers
end
but it's better to move #school = School.find(params[:id]) to before_filter

Resources