undefined method `query_parameters' in Active Admin show/panel/table_for - activeadmin

I have something very similar working in another model, so there must be something minor that I'm overlooking.
I have a model Request that has_many RequestState(s), which in return has_one.
ActiveAdmin.register Request do
show do |ad|
...
panel "Request States" do
table_for ad.request_states do
column :id
column :actor_id
column :state
column :created_at
end
end
end
end
When I try to load the page, I get:
NoMethodError in Admin::Requests#show
undefined method `query_parameters' for #<Request:0x000001062040c0>
and it's complaining about each of the "column" lines.
The underlying data seems fine since the following and similar work correctly from the rails console:
Request.find(37).request_states.pluck(:id)

I had the same problem in ActiveAdmin 1.0, and solved it without renaming my Rails model. I just renamed the resource within ActiveAdmin:
ActiveAdmin.register Request, as: "BookRequest" do ...
This also forced me to rename my path helpers, e.g., admin_request_path became admin_book_request_path everywhere. Much less intrusive than renaming the Rails model though.
See https://activeadmin.info/2-resource-customization.html#rename-the-resource

Request is a reserved Class by Rails. I think you have to use something else class name.
http://api.rubyonrails.org/classes/ActionDispatch/Request.html
But not sure, because it's namespaced...

I was getting this issue and, for me at least, it turned out to be the assignment of #request in a before_filter called in my ApplicationController:
def newsletter
#request = NewsletterRequest.new
end
Changed the #request to #newsletter_request and avoided the collision.

Related

Rails cucumber uninitialized constant User (NameError)

I'm starting with BDD (cucumber + capybara + selenium chromedriver) and TDD (rspec) with factory_bot and I'm getting an error on cucumber features - step_definitions.
uninitialized constant User (NameError)
With TDD, everything is ok, the factory bot is working fine. The problem is with the cucumber.
factories.rb
FactoryBot.define do
factory :user_role do
name {"Admin"}
query_name {"admin"}
end
factory :user do
id {1}
first_name {"Mary"}
last_name {"Jane"}
email {"mary_jane#gmail.com"}
password {"123"}
user_role_id {1}
created_at {'1/04/2020'}
end
end
support/env.rb
require 'capybara'
require 'capybara/cucumber'
require 'selenium-webdriver'
require 'factory_bot_rails'
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.configure do |config|
config.default_driver = :selenium
end
Capybara.javascript_driver = :chrome
World(FactoryBot::Syntax::Methods)
And the problem is happening here
support/hooks.rb
Before '#admin_login' do
#user = create(:user)
end
step_definitions/admin_login.rb
Given("a registered user with the email {string} with password {string} exists") do |email, password|
#user
end
I don't know why, but I can't access the user using cucumber and factory_bot.
Anybody could help me please?
I think I need to configure something on the cucumber.
What do you think guys?
First of all Luke is correct about this being a setup issue. The error is telling you that the User model cannot be found which probably means Rails is not yet loaded. I can't remember the exact details of how cucumber-rails works but one of the things it does is to make sure that each scenario becomes an extension of a Rails integration test. This ensures that all of the Rails auto-loading has taken place and that these things are available.
Secondly I'd suggest you start simpler and use a step to create your registered user rather than using a tag. Using tags for setup is a Cucumber anti-pattern.
Finally, and more controversially I'd suggest that you don't use factory-bot when cuking. FactoryBot uses a separate configuration to create model objects directly in the datastore. This bypasses any application logic around the creation of these objects, which means the objects created by FactoryBot are going to end up being different from the objects created by your application. In real life object creation involves things like auditing, sending emails, conditional logic etc. etc. To use FactoryBot you either have to duplicate that additional creation logic and behavior or ignore it (both choices are undesirable).
You can create objects for cuking much more effectively (and quicker) by using the following pattern.
Each create method in the Rails controller delegates its work to a service object e.g.
UserController
def create
#user = CreateUserService.new(params).call
end
end
Then have your cukes use a helper module to create things for you. This module will provide tools for your steps to create users, using the above service
module UserStepHelper
def create_user(params)
CreateUserService.new(default_params.merge(params))
end
def default_params
{
...
}
end
end
World UserStepHelper
Given 'there is a registered user' do
#registered_user = create_user
end
and then use that step in the background of your feature e.g.
Background:
Given there is a registered user
And I am an admin
Scenario: Admin can see registered users
When I login and view users
Then I should see a user
Notice the absence of tagging here. Its not desirable or necessary here.
You can see an extension of this approach in a sample application I did for a CukeUp talk in 2013 here https://github.com/diabolo/cuke_up/commits/master. If you follow this commit by commit starting from first commit at the bottom you will get quite a good guide to setting up a rails project with cucumber in just the first 4 or 4 commits. If you follow it through to the end (22 commits) you'll get a basic powerful framework for creating and using model objects when cuking. I realize the project is ancient and that obviously you will have to use modern versions of everything, but the principles still apply, and I use this approach in all my work and having been doing so for at least 10 years.
So if you're using rails, it's probably advised to use cucumber-rails over cucumber. This is probably an issue where your User models have not been auto-loaded in.
Cucumber auto-loads all ruby files underneath features, with env.rb first, it's almost certainly an issue with load order / load location

undefined method `signed_id' for "sdsd":String - Active Storage

I'm having an issue using rails-admin and Active Storage at the same time. I saw that you can modify the value of labels with the label method. For example, for the "user #1" thing:
def name
email
end
The problem is that I have an Asset model to upload multiple files, but I see this:
Ugly attachment id
If I try to do the same trick (just to see if every file is now called "sdsd"):
def files
'sdsd'
end
Then this shows up:
undefined method `signed_id' for "sdsd":String
I tried making a reset of the database but it didn't work at all. Any ideas? I just want to show every filename instead of that ugly id's.

How to translate error messages in Colander

How can I translate the error messages from the colander validators? The documentation just says that it's possible.
def valid_text(node, value):
raise Invalid(node, u"Some error message")
class form(colander.MappingSchema):
name = colander.SchemaNode(colander.String(), validator=valid_text)
I know that deform does it already but I need to use colander on his own.
According to the API documentation, the msg argument to Invalid can be a translation string instance. Information on working with translation strings is here.
Looks like this issue was already addressed and fixed, but it will be part of the next release. I've just added the changes from commit f6be836 and it works like a charm.

Spelling error issue in routes while scaffolding Compound js

I'm new with node and compound. While i tried to scaffold
compound g crud leaveApplication leave_code:string description:string applicable:string carry_forward:boolean limit_type:boolean lop:boolean od:boolean co:boolean leave_revision:boolean active:boolean
I was getting some errors, then i tried
compound g crud leave code:string description:string applicable:string cForward:boolean limit:boolean lop:boolean od:boolean co:boolean leave_revision:boolean active:boolean
But the error now occurred was in the name of routes
leaves GET /leaves.:format? leaves#index
leaves POST /leaves.:format? leaves#create
new_leafe GET /leaves/new.:format? leaves#new
edit_leafe GET /leaves/:id/edit.:format? leaves#edit
leafe DELETE /leaves/:id.:format? leaves#destroy
leafe PUT /leaves/:id.:format? leaves#update
leafe GET /leaves/:id.:format? leaves#show
These were the routes i was getting.
Why is that so?
it looks like compound is turning your model name into plural (=leaves) and then, instead of using your provided singular name, turning this plural name back, resulting in "leaf".
Does this make any sense? ;-) Or did I get you question wrong?
If you could provide the "some errors" and the full error message, it would be easier to help ;)
Btw, I just experienced that using camel case for models doesn't seem to be a good idea with compound.js.
It's mangeling the camelcase in some places (e.g. inside the controllers), but in others not (schema.js) creating a application with some errors...

Groovy paginate problem

I have an application written in groovy and I am having problems with the pagination of a resulting set.
I have a Controller called ReportingController. This controller has two methods called
listdoiTln and listdoiEv. Both methods are similar and at the end both have to render a list of reports. The last lines of both are as follows:
params.max = Math.min(params.max ? params.max.toInteger() : 15, 100)
render (view: 'list', model:[reportingInstanceList: reportingInstanceList, reportingInstanceTotal: i])
The list view is rendered as expected. At the footer of the list.gsp file I have:
<div class="paginateButtons">
<g:paginate controller="reporting" total="${reportingInstanceTotal}" max="25"/></div>
</div>
The list is working, the buttons for the pagination are there but it is always displayed the whole collection. Notice that I do not have files callled listdoiTln.gsp or listdoiEv.gsp. I am using list.gsp with different data models.
Surely I am doing something wrong.
Any hint?
Thanks in advance.
Luis
I had trouble with this, too, for quite a while. Try this:
Evaluate param.offset in the controller:
params.offset = params?.offset?.toInteger() ?: 0
Include the params in the model:
render (view: 'list',
model:[reportingInstanceList: reportingInstanceList,
reportingInstanceTotal: i,
params: params])
Check whether the value of reportingInstanceTotal is the value that you expect. That tripped me up for a while.
If it still doesn't work, let me know, or try looking at one of the list.gsp pages and its associated controller that are generated by the grails generate-all command.
The paginate buttons are quite cool, but there is little documentation and it takes longer than I expected to set them up.

Resources