Getting "undefined method" when attempting to order the result of a Rails query - ruby-on-rails

I'm using Ruby on Rails 5. I'm having trouble ordering results returned from this query:
#crypto_currencies = CryptoIndexCurrency
.all
.pluck("crypto_currency_id")
.order(:name)
The name field is a valid member of the table from which I want to order.
cindex=# \d crypto_currencies;
Table "public.crypto_currencies"
Column | Type | Modifiers
--------------------------+-----------------------------+----------------------------------------------------------------
id | integer | not null default nextval('crypto_currencies_id_seq'::regclass)
name | character varying |
symbol | character varying |
latest_market_cap_in_usd | bigint |
latest_total_supply | bigint |
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
Unfortunately whe I run the above I get the error:
undefined method `order' for #<Array:0x007fa3b2b27bd8>
How do I correct this?

That's right, pluck returns an array. Here is a note from documentation:
Pluck returns an Array of attribute values type-casted to match the plucked column names
where and order and other methods like that return Relation so that you can chain them. pluck should be in the end.

Say you're trying to cook eggs for yourself -- you're trying to scramble an egg carton instead of the egg inside the carton.
name is a field of CryptoCurrency, but .pluck is returning an array of CryptoCurrency objects -- the array has no name field.
You have to get the specific CryptoCurrency array element by either iterating through the array (for example, using .each... do) or accessing an element by index (#crypto_currencies[0]).
For more tutorial information on how to access the elements of an array, either by iteration or by element, please consult the official documentation.

Related

Rails select_all deserialize Postgresql array

I make a custom query that returns rows with array value term_names
Product.connection.select_all("
SELECT ARRAY_AGG(terms.name), vocabularies.name vocabulary_name
FROM terms
INNER JOIN vocabularies ON vocabularies.id = terms.vocabulary_id
GROUP BY vocabulary_name")
| term_names | vocabulary_name |
|----------------------------------------------------------------|-----------------|
| {{76,Yellow},{77,Green},{79,Blue}. | Color |
But the problem is that Rails does not want to convert {...} into ruby array and returns it as string.
[{"array_agg"=>"{Yellow,Green,Blue}", "vocabulary_name"=>"Color"}]
How can I make Rails parse result and return nested array instead?
You (me) should call cast_values method
Product.connection.select_all("
SELECT ARRAY_AGG(terms.name), vocabularies.name vocabulary_name
FROM terms
INNER JOIN vocabularies ON vocabularies.id = terms.vocabulary_id
GROUP BY vocabulary_name").cast_values

In Rails 5, why do I get undefined find_by method when I search for a model based on one of its fields?

II'm using Rails 5. I want to search for a model based on a user_id field. My table looks like this
cindex=# \d user_notifications;
Table "public.user_notifications"
Column | Type | Modifiers
--------------------+---------+-----------------------------------------------------------------
id | integer | not null default nextval('user_notifications_id_seq'::regclass)
user_id | integer |
crypto_currency_id | integer |
price | integer | not null
buy
| boolean | not null
but when I attempt to look up a model like so
#user_notification = UserNotification.find_by_user(current_user)
I get the error
undefined method `find_by_user' for UserNotification:Class
What's the simple (Rails) way to look up my field?
find_by_user is not a built in method in rails, you would have to define it in your model.
What you should use to find a record by it's id is simply Find. It will return one record matching the inputed id if it exists.
Ex:
#user_notification = UserNotifaction.find(1)
And to find by a specific field, such as a custom id, use find_by
#user_notification = UserNotifaction.find_by(custom_id: 1)

rails user-defined custom columns

I am using Ruby on Rails 4 and MySQL. I have three types. One is Biology, one is Chemistry, and another is Physics. Each type has unique fields. So I created three tables in database, each with unique column names. However, the unique column names may not be known before hand. It will be required for the user to create the column names associated with each type. I don't want to create a serialized hash, because that can become messy. I notice some other systems enable users to create user-defined columns named like column1, column2, etc.
How can I achieve these custom columns in Ruby on Rails and MySQL and still maintain all the ActiveRecord capabilities, e.g. validation, etc?
Well you don't have much options, your best solution is using NO SQL database (at least for those classes).
Lets see how can you work around using SQL. You can have a base Course model with a has_many :attributes association. In which a attribute is just a combination of a key and a value.
# attributes table
| id | key | value |
| 10 | "column1" | "value" |
| 11 | "column1" | "value" |
| 12 | "column1" | "value" |
Its going to be difficult to determin datatypes and queries covering multiple attributes at the same time.

How to get output of sql queries in FitNesse + DbFit?

I am trying to get sql query output in DBfit using i.e. !|Execute|select * from abc| but don't know how it will display in DBfit.
I think that you are looking for the Inspect Query table (you can find reference docs about it here).
!|Inspect Query|select * from abc|
When executed, this will print the resultset of the query.
First, the execute fixture is typically used for actions that do not return data, e.g.:
!|Execute|insert into tablename values (…)|
or
!|Execute|update tablename st... where...|
However, even some non-data actions have more specific commands. The above update can be done with, for example, with:
!|Update|tablename |
|field_to_change=|field_to_select|
|new value |matching value |
For returning data, use the query fixture
!|query|select Id, BatchNum from tablename|
|Id |BatchNum? |
|1 |>>Bat1 |
|2 |<<Bat1 |
As shown, just put your field names in the row below the fixture, then your data rows below that.

Newly assigned Sequence is not working

In PostgreSQL, I created a new table and assigned a new sequence to the id column. If I insert a record from the PostgreSQL console it works but when I try to import a record from from Rails, it raises an exception that it is unable to find the associated sequence.
Here is the table:
\d+ user_messages;
Table "public.user_messages"
Column | Type | Modifiers | Storage | Description
-------------+-----------------------------+------------------------------------------------------------+----------+-------------
id | integer | not null default nextval('new_user_messages_id'::regclass) | plain |
But when I try to get the sequence with the SQL query which Rails uses, it returns NULL:
select pg_catalog.pg_get_serial_sequence('user_messages', 'id');
pg_get_serial_sequence
------------------------
(1 row)
The error being raised by Rails is:
UserMessage.import [UserMessage.new]
NoMethodError: undefined method `split' for nil:NilClass
from /app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:910:in `default_sequence_name'
This problem only occurs when I use the ActiveRecord extension for importing bulk records, single records get saved through ActiveRecord.
How do I fix it?
I think your problem is that you set all this up by hand rather than by using a serial column. When you use a serial column, PostgreSQL will create the sequence, set up the appropriate default value, and ensure that the sequence is owned by the table and column in question. From the fine manual:
pg_get_serial_sequence(table_name, column_name)
get name of the sequence that a serial or bigserial column uses
But you're not using serial or bigserial so pg_get_serial_sequence won't help.
You can remedy this by doing:
alter sequence new_user_messages_id owned by user_messages.id
I'm not sure if this is a complete solution and someone (hi Erwin) will probably fill in the missing bits.
You can save yourself some trouble here by using serial as the data type of your id column. That will create and hook up the sequence for you.
For example:
=> create sequence seq_test_id;
=> create table seq_test (id integer not null default nextval('seq_test_id'::regclass));
=> select pg_catalog.pg_get_serial_sequence('seq_test','id');
pg_get_serial_sequence
------------------------
(1 row)
=> alter sequence seq_test_id owned by seq_test.id;
=> select pg_catalog.pg_get_serial_sequence('seq_test','id');
pg_get_serial_sequence
------------------------
public.seq_test_id
(1 row)

Resources