aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb2
-rw-r--r--actiontext/lib/action_text/attribute.rb7
-rw-r--r--actiontext/test/dummy/app/models/message.rb3
-rw-r--r--actiontext/test/dummy/app/models/review.rb5
-rw-r--r--actiontext/test/dummy/db/migrate/20190317200724_create_reviews.rb8
-rw-r--r--actiontext/test/dummy/db/schema.rb8
-rw-r--r--actiontext/test/unit/model_test.rb16
-rw-r--r--activerecord/lib/arel/insert_manager.rb6
-rw-r--r--activerecord/lib/arel/nodes.rb1
-rw-r--r--activerecord/lib/arel/nodes/values.rb16
-rw-r--r--activerecord/lib/arel/nodes/values_list.rb19
-rw-r--r--activerecord/lib/arel/visitors/depth_first.rb2
-rw-r--r--activerecord/lib/arel/visitors/dot.rb4
-rw-r--r--activerecord/lib/arel/visitors/to_sql.rb25
-rw-r--r--activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb10
-rw-r--r--activerecord/test/cases/arel/insert_manager_test.rb19
-rw-r--r--activerecord/test/cases/arel/visitors/depth_first_test.rb2
-rw-r--r--activerecord/test/cases/arel/visitors/dot_test.rb2
-rw-r--r--activerecord/test/cases/arel/visitors/to_sql_test.rb4
20 files changed, 86 insertions, 83 deletions
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index cb109c6ad8..4bf8d90b69 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -431,7 +431,7 @@ module ActionController #:nodoc:
The browser returned a 'null' origin for a request with origin-based forgery protection turned on. This usually
means you have the 'no-referrer' Referrer-Policy header enabled, or that the request came from a site that
refused to give its origin. This makes it impossible for Rails to verify the source of the requests. Likely the
- best solution is to change your referrer policy to something less strict like same-origin or strict-same-origin.
+ best solution is to change your referrer policy to something less strict like same-origin or strict-origin.
If you cannot change the referrer policy, you can disable origin checking with the
Rails.application.config.action_controller.forgery_protection_origin_check setting.
MSG
diff --git a/actiontext/lib/action_text/attribute.rb b/actiontext/lib/action_text/attribute.rb
index f226dd21bd..f9a604096c 100644
--- a/actiontext/lib/action_text/attribute.rb
+++ b/actiontext/lib/action_text/attribute.rb
@@ -34,14 +34,11 @@ module ActionText
end
CODE
- has_one :"rich_text_#{name}", -> { where(name: name) }, class_name: "ActionText::RichText", as: :record, inverse_of: :record, dependent: :destroy
+ has_one :"rich_text_#{name}", -> { where(name: name) },
+ class_name: "ActionText::RichText", as: :record, inverse_of: :record, autosave: true, dependent: :destroy
scope :"with_rich_text_#{name}", -> { includes("rich_text_#{name}") }
scope :"with_rich_text_#{name}_and_embeds", -> { includes("rich_text_#{name}": { embeds_attachments: :blob }) }
-
- after_save do
- public_send(name).save if public_send(name).changed?
- end
end
end
end
diff --git a/actiontext/test/dummy/app/models/message.rb b/actiontext/test/dummy/app/models/message.rb
index 9ea4dbfe78..7bce50753c 100644
--- a/actiontext/test/dummy/app/models/message.rb
+++ b/actiontext/test/dummy/app/models/message.rb
@@ -1,4 +1,7 @@
class Message < ApplicationRecord
has_rich_text :content
has_rich_text :body
+
+ has_one :review
+ accepts_nested_attributes_for :review
end
diff --git a/actiontext/test/dummy/app/models/review.rb b/actiontext/test/dummy/app/models/review.rb
new file mode 100644
index 0000000000..e54a37685d
--- /dev/null
+++ b/actiontext/test/dummy/app/models/review.rb
@@ -0,0 +1,5 @@
+class Review < ApplicationRecord
+ belongs_to :message
+
+ has_rich_text :content
+end
diff --git a/actiontext/test/dummy/db/migrate/20190317200724_create_reviews.rb b/actiontext/test/dummy/db/migrate/20190317200724_create_reviews.rb
new file mode 100644
index 0000000000..96e0eab287
--- /dev/null
+++ b/actiontext/test/dummy/db/migrate/20190317200724_create_reviews.rb
@@ -0,0 +1,8 @@
+class CreateReviews < ActiveRecord::Migration[6.0]
+ def change
+ create_table :reviews do |t|
+ t.belongs_to :message, null: false
+ t.string :author_name, null: false
+ end
+ end
+end
diff --git a/actiontext/test/dummy/db/schema.rb b/actiontext/test/dummy/db/schema.rb
index 60ccbd4873..03e99b29d2 100644
--- a/actiontext/test/dummy/db/schema.rb
+++ b/actiontext/test/dummy/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2019_03_05_172303) do
+ActiveRecord::Schema.define(version: 2019_03_17_200724) do
create_table "action_text_rich_texts", force: :cascade do |t|
t.string "name", null: false
@@ -61,5 +61,11 @@ ActiveRecord::Schema.define(version: 2019_03_05_172303) do
t.datetime "updated_at", precision: 6, null: false
end
+ create_table "reviews", force: :cascade do |t|
+ t.integer "message_id", null: false
+ t.string "author_name", null: false
+ t.index ["message_id"], name: "index_reviews_on_message_id"
+ end
+
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
end
diff --git a/actiontext/test/unit/model_test.rb b/actiontext/test/unit/model_test.rb
index d56363adc0..f4328ba2ce 100644
--- a/actiontext/test/unit/model_test.rb
+++ b/actiontext/test/unit/model_test.rb
@@ -49,8 +49,22 @@ class ActionText::ModelTest < ActiveSupport::TestCase
assert_equal "Hello world", message.content.to_plain_text
end
- test "save body" do
+ test "saving body" do
message = Message.create(subject: "Greetings", body: "<h1>Hello world</h1>")
assert_equal "Hello world", message.body.to_plain_text
end
+
+ test "saving content via nested attributes" do
+ message = Message.create! subject: "Greetings", content: "<h1>Hello world</h1>",
+ review_attributes: { author_name: "Marcia", content: "Nice work!" }
+ assert_equal "Nice work!", message.review.content.to_plain_text
+ end
+
+ test "updating content via nested attributes" do
+ message = Message.create! subject: "Greetings", content: "<h1>Hello world</h1>",
+ review_attributes: { author_name: "Marcia", content: "Nice work!" }
+
+ message.update! review_attributes: { id: message.review.id, content: "Great work!" }
+ assert_equal "Great work!", message.review.reload.content.to_plain_text
+ end
end
diff --git a/activerecord/lib/arel/insert_manager.rb b/activerecord/lib/arel/insert_manager.rb
index c90fc33a48..cb31e3060b 100644
--- a/activerecord/lib/arel/insert_manager.rb
+++ b/activerecord/lib/arel/insert_manager.rb
@@ -33,13 +33,13 @@ module Arel # :nodoc: all
@ast.columns << column
values << value
end
- @ast.values = create_values values, @ast.columns
+ @ast.values = create_values(values)
end
self
end
- def create_values(values, columns)
- Nodes::Values.new values, columns
+ def create_values(values)
+ Nodes::ValuesList.new([values])
end
def create_values_list(rows)
diff --git a/activerecord/lib/arel/nodes.rb b/activerecord/lib/arel/nodes.rb
index 5af0e532e2..2f6dd9bc45 100644
--- a/activerecord/lib/arel/nodes.rb
+++ b/activerecord/lib/arel/nodes.rb
@@ -45,7 +45,6 @@ require "arel/nodes/and"
require "arel/nodes/function"
require "arel/nodes/count"
require "arel/nodes/extract"
-require "arel/nodes/values"
require "arel/nodes/values_list"
require "arel/nodes/named_function"
diff --git a/activerecord/lib/arel/nodes/values.rb b/activerecord/lib/arel/nodes/values.rb
deleted file mode 100644
index 650248dc04..0000000000
--- a/activerecord/lib/arel/nodes/values.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-module Arel # :nodoc: all
- module Nodes
- class Values < Arel::Nodes::Binary
- alias :expressions :left
- alias :expressions= :left=
- alias :columns :right
- alias :columns= :right=
-
- def initialize(exprs, columns = [])
- super
- end
- end
- end
-end
diff --git a/activerecord/lib/arel/nodes/values_list.rb b/activerecord/lib/arel/nodes/values_list.rb
index 27109848e4..1a9d9ebf01 100644
--- a/activerecord/lib/arel/nodes/values_list.rb
+++ b/activerecord/lib/arel/nodes/values_list.rb
@@ -2,23 +2,8 @@
module Arel # :nodoc: all
module Nodes
- class ValuesList < Node
- attr_reader :rows
-
- def initialize(rows)
- @rows = rows
- super()
- end
-
- def hash
- @rows.hash
- end
-
- def eql?(other)
- self.class == other.class &&
- self.rows == other.rows
- end
- alias :== :eql?
+ class ValuesList < Unary
+ alias :rows :expr
end
end
end
diff --git a/activerecord/lib/arel/visitors/depth_first.rb b/activerecord/lib/arel/visitors/depth_first.rb
index 892d670c79..109afb7402 100644
--- a/activerecord/lib/arel/visitors/depth_first.rb
+++ b/activerecord/lib/arel/visitors/depth_first.rb
@@ -36,6 +36,7 @@ module Arel # :nodoc: all
alias :visit_Arel_Nodes_Descending :unary
alias :visit_Arel_Nodes_UnqualifiedColumn :unary
alias :visit_Arel_Nodes_OptimizerHints :unary
+ alias :visit_Arel_Nodes_ValuesList :unary
def function(o)
visit o.expressions
@@ -103,7 +104,6 @@ module Arel # :nodoc: all
alias :visit_Arel_Nodes_Regexp :binary
alias :visit_Arel_Nodes_RightOuterJoin :binary
alias :visit_Arel_Nodes_TableAlias :binary
- alias :visit_Arel_Nodes_Values :binary
alias :visit_Arel_Nodes_When :binary
def visit_Arel_Nodes_StringJoin(o)
diff --git a/activerecord/lib/arel/visitors/dot.rb b/activerecord/lib/arel/visitors/dot.rb
index ffcbb7a7ab..37803ce0c0 100644
--- a/activerecord/lib/arel/visitors/dot.rb
+++ b/activerecord/lib/arel/visitors/dot.rb
@@ -46,8 +46,8 @@ module Arel # :nodoc: all
visit_edge o, "distinct"
end
- def visit_Arel_Nodes_Values(o)
- visit_edge o, "expressions"
+ def visit_Arel_Nodes_ValuesList(o)
+ visit_edge o, "rows"
end
def visit_Arel_Nodes_StringJoin(o)
diff --git a/activerecord/lib/arel/visitors/to_sql.rb b/activerecord/lib/arel/visitors/to_sql.rb
index 7e3e265208..583f920290 100644
--- a/activerecord/lib/arel/visitors/to_sql.rb
+++ b/activerecord/lib/arel/visitors/to_sql.rb
@@ -159,7 +159,7 @@ module Arel # :nodoc: all
when Nodes::SqlLiteral, Nodes::BindParam
collector = visit(value, collector)
else
- collector << quote(value)
+ collector << quote(value).to_s
end
collector << COMMA unless k == row_len
end
@@ -169,25 +169,6 @@ module Arel # :nodoc: all
collector
end
- def visit_Arel_Nodes_Values(o, collector)
- collector << "VALUES ("
-
- len = o.expressions.length - 1
- o.expressions.each_with_index { |value, i|
- case value
- when Nodes::SqlLiteral, Nodes::BindParam
- collector = visit value, collector
- else
- collector << quote(value).to_s
- end
- unless i == len
- collector << COMMA
- end
- }
-
- collector << ")"
- end
-
def visit_Arel_Nodes_SelectStatement(o, collector)
if o.with
collector = visit o.with, collector
@@ -805,7 +786,9 @@ module Arel # :nodoc: all
end
def sanitize_as_sql_comment(o)
- o.expr.map { |v| v.gsub(%r{ /\*\+?\s* | \s*\*/ }x, "") }
+ o.expr.map { |v|
+ v.gsub(%r{ (/ (?: | \g<1>) \*) \+? \s* | \s* (\* (?: | \g<2>) /) }x, "")
+ }
end
def collect_optimizer_hints(o, collector)
diff --git a/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb b/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb
index 31a002e935..b9794c5710 100644
--- a/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb
@@ -13,13 +13,23 @@ if supports_optimizer_hints?
posts = posts.select(:id).where(author_id: [0, 1])
assert_includes posts.explain, "| index | index_posts_on_author_id | index_posts_on_author_id |"
end
+ end
+ def test_optimizer_hints_is_sanitized
assert_sql(%r{\ASELECT /\*\+ NO_RANGE_OPTIMIZATION\(posts index_posts_on_author_id\) \*/}) do
posts = Post.optimizer_hints("/*+ NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id) */")
posts = posts.select(:id).where(author_id: [0, 1])
assert_includes posts.explain, "| index | index_posts_on_author_id | index_posts_on_author_id |"
end
+ assert_sql(%r{\ASELECT /\*\+ `posts`\.\*, \*/}) do
+ posts = Post.optimizer_hints("**// `posts`.*, //**")
+ posts = posts.select(:id).where(author_id: [0, 1])
+ assert_equal({ "id" => 1 }, posts.first.as_json)
+ end
+ end
+
+ def test_optimizer_hints_with_unscope
assert_sql(%r{\ASELECT `posts`\.`id`}) do
posts = Post.optimizer_hints("/*+ NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id) */")
posts = posts.select(:id).where(author_id: [0, 1])
diff --git a/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb b/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb
index 4fac7ffdc0..5e4bf232e1 100644
--- a/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb
@@ -17,13 +17,23 @@ if supports_optimizer_hints?
posts = posts.select(:id).where(author_id: [0, 1])
assert_includes posts.explain, "Seq Scan on posts"
end
+ end
+ def test_optimizer_hints_is_sanitized
assert_sql(%r{\ASELECT /\*\+ SeqScan\(posts\) \*/}) do
posts = Post.optimizer_hints("/*+ SeqScan(posts) */")
posts = posts.select(:id).where(author_id: [0, 1])
assert_includes posts.explain, "Seq Scan on posts"
end
+ assert_sql(%r{\ASELECT /\*\+ "posts"\.\*, \*/}) do
+ posts = Post.optimizer_hints("**// \"posts\".*, //**")
+ posts = posts.select(:id).where(author_id: [0, 1])
+ assert_equal({ "id" => 1 }, posts.first.as_json)
+ end
+ end
+
+ def test_optimizer_hints_with_unscope
assert_sql(%r{\ASELECT "posts"\."id"}) do
posts = Post.optimizer_hints("/*+ SeqScan(posts) */")
posts = posts.select(:id).where(author_id: [0, 1])
diff --git a/activerecord/test/cases/arel/insert_manager_test.rb b/activerecord/test/cases/arel/insert_manager_test.rb
index 2376ad8d37..79b85742ee 100644
--- a/activerecord/test/cases/arel/insert_manager_test.rb
+++ b/activerecord/test/cases/arel/insert_manager_test.rb
@@ -11,19 +11,18 @@ module Arel
end
describe "insert" do
- it "can create a Values node" do
+ it "can create a ValuesList node" do
manager = Arel::InsertManager.new
- values = manager.create_values %w{ a b }, %w{ c d }
+ values = manager.create_values_list([%w{ a b }, %w{ c d }])
- assert_kind_of Arel::Nodes::Values, values
- assert_equal %w{ a b }, values.left
- assert_equal %w{ c d }, values.right
+ assert_kind_of Arel::Nodes::ValuesList, values
+ assert_equal [%w{ a b }, %w{ c d }], values.rows
end
it "allows sql literals" do
manager = Arel::InsertManager.new
manager.into Table.new(:users)
- manager.values = manager.create_values [Arel.sql("*")], %w{ a }
+ manager.values = manager.create_values([Arel.sql("*")])
manager.to_sql.must_be_like %{
INSERT INTO \"users\" VALUES (*)
}
@@ -186,9 +185,9 @@ module Arel
manager = Arel::InsertManager.new
manager.into table
- manager.values = Nodes::Values.new [1]
+ manager.values = Nodes::ValuesList.new([[1], [2]])
manager.to_sql.must_be_like %{
- INSERT INTO "users" VALUES (1)
+ INSERT INTO "users" VALUES (1), (2)
}
end
@@ -210,11 +209,11 @@ module Arel
manager = Arel::InsertManager.new
manager.into table
- manager.values = Nodes::Values.new [1, "aaron"]
+ manager.values = Nodes::ValuesList.new([[1, "aaron"], [2, "david"]])
manager.columns << table[:id]
manager.columns << table[:name]
manager.to_sql.must_be_like %{
- INSERT INTO "users" ("id", "name") VALUES (1, 'aaron')
+ INSERT INTO "users" ("id", "name") VALUES (1, 'aaron'), (2, 'david')
}
end
end
diff --git a/activerecord/test/cases/arel/visitors/depth_first_test.rb b/activerecord/test/cases/arel/visitors/depth_first_test.rb
index f94ad521d7..4a57608411 100644
--- a/activerecord/test/cases/arel/visitors/depth_first_test.rb
+++ b/activerecord/test/cases/arel/visitors/depth_first_test.rb
@@ -33,6 +33,7 @@ module Arel
Arel::Nodes::Ordering,
Arel::Nodes::StringJoin,
Arel::Nodes::UnqualifiedColumn,
+ Arel::Nodes::ValuesList,
Arel::Nodes::Limit,
Arel::Nodes::Else,
].each do |klass|
@@ -116,7 +117,6 @@ module Arel
Arel::Nodes::NotIn,
Arel::Nodes::Or,
Arel::Nodes::TableAlias,
- Arel::Nodes::Values,
Arel::Nodes::As,
Arel::Nodes::DeleteStatement,
Arel::Nodes::JoinSource,
diff --git a/activerecord/test/cases/arel/visitors/dot_test.rb b/activerecord/test/cases/arel/visitors/dot_test.rb
index 6b3c132f83..ade53c358e 100644
--- a/activerecord/test/cases/arel/visitors/dot_test.rb
+++ b/activerecord/test/cases/arel/visitors/dot_test.rb
@@ -37,6 +37,7 @@ module Arel
Arel::Nodes::Offset,
Arel::Nodes::Ordering,
Arel::Nodes::UnqualifiedColumn,
+ Arel::Nodes::ValuesList,
Arel::Nodes::Limit,
].each do |klass|
define_method("test_#{klass.name.gsub('::', '_')}") do
@@ -61,7 +62,6 @@ module Arel
Arel::Nodes::NotIn,
Arel::Nodes::Or,
Arel::Nodes::TableAlias,
- Arel::Nodes::Values,
Arel::Nodes::As,
Arel::Nodes::DeleteStatement,
Arel::Nodes::JoinSource,
diff --git a/activerecord/test/cases/arel/visitors/to_sql_test.rb b/activerecord/test/cases/arel/visitors/to_sql_test.rb
index 4bfa799a96..625e37f1c0 100644
--- a/activerecord/test/cases/arel/visitors/to_sql_test.rb
+++ b/activerecord/test/cases/arel/visitors/to_sql_test.rb
@@ -23,9 +23,9 @@ module Arel
sql.must_be_like "?"
end
- it "does not quote BindParams used as part of a Values" do
+ it "does not quote BindParams used as part of a ValuesList" do
bp = Nodes::BindParam.new(1)
- values = Nodes::Values.new([bp])
+ values = Nodes::ValuesList.new([[bp]])
sql = compile values
sql.must_be_like "VALUES (?)"
end